第二十八讲:基础三里氏代换原则
JAVA中一个非常重要的原则:多态.
// public class MainClass { public static void main(String[] args) { Person person = new Person(); display(person); Person man = new Man(); display(man); } //public static void display(Person person){ public static void display(Man man){ //person.display(); man.display(); } }
//JAVA中一个非常重要的原则:多态. public class Man extends Person { public void display(){ System.out.println("this is man"); } }
public class Person{ public void display(){ System.out.println("this is a person"); } }
从智能工具上来讲企鹅当然是属于鸟类,从程序设计上来讲企鹅它到底是鸟类吗?
传父类的地方可以用子类替换.
企鹅是鸟类吗?同样是大话设计模式里面提到的知识点.
java里面的父类引用指向子类对象和里氏替换原则是极其类似的.父类引用指向子类对象同样也是多态的条件.多态的三个条件:第一个要有继承,第二个要有重写,第三个要有父类引用,父类引用指向子类对象.这就是多态.
package com.ibeifeng.ex2; public interface Bird { public void fly();//飞 //public void bushi();//捕食 }
package com.ibeifeng.ex2; public class Laoying implements Bird { @Override public void fly() { // TODO Auto-generated method stub System.out.println("老鹰在飞"); } }
package com.ibeifeng.ex2; public class MainClass { public static void main(String[] args) { fly(new Laoying()); fly(new Maque()); //fly(new Qie());//不能把一个企鹅传进来,因为企鹅根本就不能飞. } public static void fly(Bird bird){ bird.fly(); } }
package com.ibeifeng.ex2; public class Maque implements Bird { @Override public void fly() { // TODO Auto-generated method stub System.out.println("麻雀在飞"); } }
package com.ibeifeng.ex2; //public class Qie implements Bird { public class Qie { /*@Override public void fly() { // TODO Auto-generated method stub }*/ }
《java与模式》里面的一个问题:
小学生会说:正方形是一种特殊的长方形.正方形的长和宽是相等的.
里氏替换原则是能够放父类的地方就可以放子类.里氏替换原则的一个重要的地方是使用父类的地方可以使用子类.
正方形和长方形是相互独立的两个类,没有继承关系那就不存在里氏替换关系.
Java的特性:父类引用可以指向子类对象.成功地骗过了编译器.但是它真的符合里氏替换原则吗?
所以正方形根本不是长方形的子类,只不过是我们把它强求在里面而已.所以说强扭的瓜不甜.我们强求地把ZhengFX extends ChangFX
里氏替换原则的重点是:如果使用父类的地方一定适用于子类.你可以欺骗java编译器.java编译器不能检查是否符合里氏替换原则,因为java编译器不能理解很多业务逻辑,它所能识别的是子类是不是继承父类以及实现父类的方法.
因为使用了里氏替换原则才使得前面的开发封闭原则具有扩展性.设计软件的时候会设计一个接口接受父类,而真正使用到的是它的子类.使用到父类的地方也可以使用子类保证了子类可用.
package com.ibeifeng.ex3; //public class ChangFX { public class ChangFX implements Sibianxing{ private long width; private long height; public long getWidth() { return width; } public void setWidth(long width) { this.width = width; } public long getHeight() { return height; } public void setHeight(long height) { this.height = height; } }
package com.ibeifeng.ex3; public class MainClass { public static void main(String[] args) { ChangFX changfx = new ChangFX(); //Sibianxing changfx = new ChangFX(); changfx.setHeight(10); changfx.setWidth(20); test(changfx); //resize(changfx); //ChangFX zhengfx = new ZhengFX(); ZhengFX zhengfx = new ZhengFX(); zhengfx.setHeight(10); test(zhengfx); //resize(zhengfx); } /* public static void test(ChangFX changFx){ System.out.println(changFx.getHeight()); System.out.println(changFx.getWidth()); }*/ public static void test(Sibianxing sibianxing){ System.out.println(sibianxing.getHeight()); System.out.println(sibianxing.getWidth()); } /* public static void resize(ChangFX changfx){ while(changfx.getHeight() <= changfx.getWidth()){ changfx.setHeight(changfx.getHeight() + 1); test(changfx); } }*/ /* public static void resize(Sibianxing sibianxing){ while(sibianxing.getHeight() <= sibianxing.getWidth()){ sibianxing.setHeight(sibianxing.getHeight() + 1); test(sibianxing); } }*/ }
package com.ibeifeng.ex3; public interface Sibianxing { /* public void getWidth(); public void getHeight();*/ public long getWidth(); public long getHeight(); }
package com.ibeifeng.ex3; //public class ZhengFX { //public class ZhengFX extends ChangFX{ public class ZhengFX implements Sibianxing{ private long side; public long getSide() { return side; } public void setSide(long side) { this.side = side; } @Override public long getWidth() { // TODO Auto-generated method stub //return super.getWidth(); return this.getSide(); } //@Override public void setWidth(long width) { // TODO Auto-generated method stub //super.setWidth(width); this.setSide(width); } @Override public long getHeight() { // TODO Auto-generated method stub //return super.getHeight(); return this.getSide(); } //@Override public void setHeight(long height) { // TODO Auto-generated method stub //super.setHeight(height); this.setSide(height); } }