设计模式-里氏替换原则

2020-04-01  本文已影响0人  吃番茄的土拨鼠

里氏替换原则

定义:使用父类的地方都能使用子类替换

要求:
1.子类的入参类型要比父类方法入参更宽(入参类型是父类入参类型的类型或者父类型)
2.子类的返回值类型父类方法要更窄(返回值类型是父类的返回类型或者子类型)
在java中就是要求子类不要Override父类的方法,保证子类实例化对象还是能调用到父类方法


代码示例如下

 public static void main(String[] args) {
        //初始我们只想有一个能“食物”的动物
        Animal animal = new Animal();
        Food food = new Food();
        animal.eat(food);

        //我们把这个动物增强,让它能吃鱼。但是我们还是希望它作为动物本身还是可以继续吃"食物"
        Cat cat = new Cat();
        cat.eat(food);
        cat.eat(new Fish());

        //我们把这个动物增强,让它能咩咩叫。但是我们还是希望它作为动物本身还是可以继续吃"食物"
        //我们发现它已经不能继续吃“食物"了,而是开始吃草了。因为它无法调用到父类的方法了
        Sheep sheep = new Sheep();
        sheep.eat(food);
        sheep.eat(new Grass());
    }

    public static class Animal {
        protected String name;

        public void eat(Food food) {
            String subjectName = this.name == null ? "animal" : this.name;
            System.out.println(String.format("%s eat food", subjectName));
        }

        public void setName(String name) {
            this.name = name;
        }

    }

    //符合LSP
    public static class Cat extends Animal {

        public void eat(Fish fish) {
            System.out.println(String.format("%s  eat fish", this.name));
        }


        public Cat() {
            this.setName("cat");
        }
    }

    //不符合LSP
    public static class Sheep extends Animal {

        @Override
        public void eat(Food food) {
            System.out.println(String.format("%s eat grass", this.name));
        }

        public void meimie(Grass grass) {
            System.out.println(String.format("%s can miemie", this.name));
        }


        public Sheep() {
            this.setName("sheep");
        }
    }


    public static class Fish extends Food {

    }

    public static class Grass extends Food {
    }


    public static class Food {

    }
上一篇下一篇

猜你喜欢

热点阅读