1    代码演练

1.1  继承关系判别(是否是真正意义的继承)

1.2  入参控制

1.3  出参控制

 

 

 

1    代码演练

1.1  继承关系判别(是否是真正意义的继承)(其实我觉得这个例子有点牵强)

1.1.1  反例

结论:

确定继承关系的时候一定要判断好,是否父类的方法子类可以继承。传统意义的正方形是矩形的子类,在这里是不适用的。

测试类1:

package com.geely.design.principle.liskovSubstitutation;

public class TestSquare {
    public static void resize(Rectangle rectangle){
        while(rectangle.getWidth()<=rectangle.getLength()){
            rectangle.setWidth(rectangle.getWidth()+1);
            System.out.println("长为"+rectangle.getLength()+"****************宽为"+rectangle.getWidth());
        }
        
    }
    public static void main(String [] args){
       Rectangle rectangle = new Rectangle();
       rectangle.setWidth(10);
       rectangle.setLength(20);
       resize(rectangle);
    }

//    public static void main(String [] args){
//        Square square = new Square();
//        square.setLength(10);
//        resize(square);
//    }
}

 

打印结果1:

"C:\Program Files\Java\jdk1.6.0_43\bin\java.exe" "-javaagent:D:\java\devolopKit\idea\anZh\IntelliJ IDEA Community Edition 2018.1.4\lib\idea_rt.jar=17363:D:\java\devolopKit\idea\anZh\IntelliJ IDEA Community Edition 2018.1.4\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.6.0_43\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\jce.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\resources.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\rt.jar;F:\xiangmu3\Xin\Idea\out\production\design_pattern" com.geely.design.principle.liskovSubstitutation.TestSquare
长为20****************宽为11
长为20****************宽为12
长为20****************宽为13
长为20****************宽为14
长为20****************宽为15
长为20****************宽为16
长为20****************宽为17
长为20****************宽为18
长为20****************宽为19
长为20****************宽为20
长为20****************宽为21

Process finished with exit code 0

 

测试类2:

package com.geely.design.principle.liskovSubstitutation;

public class TestSquare {
    public static void resize(Rectangle rectangle){
        while(rectangle.getWidth()<=rectangle.getLength()){
            rectangle.setWidth(rectangle.getWidth()+1);
            System.out.println("长为"+rectangle.getLength()+"****************宽为"+rectangle.getWidth());
        }
        
    }
//    public static void main(String [] args){
//       Rectangle rectangle = new Rectangle();
//       rectangle.setWidth(10);
//       rectangle.setLength(20);
//       resize(rectangle);
//    }

    public static void main(String [] args){
        Square square = new Square();
        square.setLength(10);
        resize(square);
    }
}

 

打印结果2:

**************************************
长为241350****************宽为241350
长为241351****************宽为241351
长为241352****************宽为241352
长为241353****************宽为241353
长为241354****************宽为241354
**************************************

 

矩形类:

package com.geely.design.principle.liskovSubstitutation;

public class Rectangle {
    private long length;
    private long width;

    public long getLength() {
        return length;
    }

    public void setLength(long length) {
        this.length = length;
    }

    public long getWidth() {
        return width;
    }

    public void setWidth(long width) {
        this.width = width;
    }
}

 

正方形类:

package com.geely.design.principle.liskovSubstitutation;

public class Square extends Rectangle {
    private long sideLength;

    public long getSideLength() {
        return sideLength;
    }

    public void setSideLength(long sideLength) {
        this.sideLength = sideLength;
    }

    @Override
    public long getLength() {
        return getSideLength();
    }

    @Override
    public void setLength(long length) {
        setSideLength(length);
    }

    @Override
    public long getWidth() {
        return getSideLength();
    }

    @Override
    public void setWidth(long width) {
        setSideLength(width);
    }
}

 

1.1.2  正方形矩形实现四边形

结论:

子类行为规则应与父类行为规则一致,如果子类达不到这一点,则会违背里氏替换原则,违背里氏替换原则会怎样?继承逻辑混乱,代码不便于维护

 

测试类:

package com.geely.design.principle.liskovSubstitutation;

public class TestSquare2 {
    public static void resize(Rectangle rectangle){
        while(rectangle.getWidth()<=rectangle.getLength()){
            rectangle.setWidth(rectangle.getWidth()+1);
            System.out.println("长为"+rectangle.getLength()+"****************宽为"+rectangle.getWidth());
        }
        
    }
//    public static void main(String [] args){
//       Rectangle rectangle = new Rectangle();
//       rectangle.setWidth(10);
//       rectangle.setLength(20);
//       resize(rectangle);
//    }

    public static void main(String [] args){
        Square square = new Square();
        square.setSideLength(10);
        resize(square);
    }
}

 

四边形接口:

package com.geely.design.principle.liskovSubstitutation;

public interface Quadrangle {
    long getWidth();
    long getLength();
} 

 

矩形类:

package com.geely.design.principle.liskovSubstitutation;

public class Rectangle implements Quadrangle{
    private long length;
    private long width;

    public void setLength(long length) {
        this.length = length;
    }

    public void setWidth(long width) {
        this.width = width;
    }

    @Override
    public long getWidth() {
        return width;
    }

    @Override
    public long getLength() {
        return length;
    }
}

 

正方形类:

package com.geely.design.principle.liskovSubstitutation;

public class Square implements Quadrangle{
    private long sideLength;

    public long getSideLength() {
        return sideLength;
    }
    public void setSideLength(long sideLength) {
        this.sideLength = sideLength;
    }

    @Override
    public long getWidth() {
        return sideLength;
    }

    @Override
    public long getLength() {
        return sideLength;
    }
}

 

1.2  入参控制

1.2.1  里氏替换原则正例

结论:

重载的时候入参更加宽松,可以不引起逻辑的混乱。

 

测试类:

package com.geely.design.principle.liskovSubstitutation.inputmethod;

import java.util.HashMap;

public class TestChild {
    public static void main(String [] args){
        Child child = new Child();
        HashMap hashMap = new HashMap();
        child.method(hashMap);
    }
}

 

子类:

import java.util.HashMap;
import java.util.Map;

public class Child extends  Base{
//    @Override
//    public void method(HashMap hashMap) {
//        System.out.println("执行子类的HashMap方法");
//    }

    /**
     * 子类重载
     * 重载的时候入参 Map比 Hashmap宽松,此时执行的时候会执行父类,不执行重载的类
     * @param hashMap
     */
    public void method(Map Map) {
        System.out.println("执行子类Map方法");
    }
}

 

父类:

package com.geely.design.principle.liskovSubstitutation.inputmethod;

import java.util.HashMap;

public class Base {
    public void method(HashMap hashMap){
        System.out.println("执行父类HashMap方法");
    }

}

 

打印结果:

"C:\Program Files\Java\jdk1.6.0_43\bin\java.exe" "-javaagent:D:\java\devolopKit\idea\anZh\IntelliJ IDEA Community Edition 2018.1.4\lib\idea_rt.jar=21089:D:\java\devolopKit\idea\anZh\IntelliJ IDEA Community Edition 2018.1.4\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.6.0_43\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\jce.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\resources.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\rt.jar;F:\xiangmu3\Xin\Idea\out\production\design_pattern" com.geely.design.principle.liskovSubstitutation.inputmethod.TestChild
执行父类HashMap方法

Process finished with exit code 0

 

1.2.2  里氏替换原则反例

测试类:

package com.geely.design.principle.liskovSubstitutation.inputmethod;

import java.util.HashMap;

public class TestChild {
    public static void main(String [] args){
        Child child = new Child();
        HashMap hashMap = new HashMap();
        child.method(hashMap);
    }
}

 

子类:

package com.geely.design.principle.liskovSubstitutation.inputmethod;

import java.util.HashMap;
import java.util.Map;

public class Child extends  Base{
//    @Override
//    public void method(Map map) {
//        super.method(map);
//    }

    public void method(HashMap hashMap) {
        System.out.println("执行子类HashMap方法");
    }
}

 

父类:

package com.geely.design.principle.liskovSubstitutation.inputmethod;

import java.util.HashMap;
import java.util.Map;

public class Base {
    public void method(Map map){
        System.out.println("执行父类HashMap方法");
    }

}

 

打印日志:

"C:\Program Files\Java\jdk1.6.0_43\bin\java.exe" "-javaagent:D:\java\devolopKit\idea\anZh\IntelliJ IDEA Community Edition 2018.1.4\lib\idea_rt.jar=21674:D:\java\devolopKit\idea\anZh\IntelliJ IDEA Community Edition 2018.1.4\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.6.0_43\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\jce.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\resources.jar;C:\Program Files\Java\jdk1.6.0_43\jre\lib\rt.jar;F:\xiangmu3\Xin\Idea\out\production\design_pattern" com.geely.design.principle.liskovSubstitutation.inputmethod.TestChild
执行子类HashMap方法

Process finished with exit code 0

 

1.3  出参控制

1.3.1  反例

结论:

子类的出参如果包含父类,会直接报错。

 

子类:

package com.geely.design.principle.liskovSubstitutation.outputmethod;

import java.util.Map;

public class Child extends Base {
    @Override
    public Object method() {
        return null;
    }
}

 

父类:

package com.geely.design.principle.liskovSubstitutation.outputmethod;

import java.util.Map;

public abstract class Base {
    public abstract Map method();
}

 

posted on 2019-07-20 15:20  菜鸟乙  阅读(284)  评论(0编辑  收藏  举报