本文目录一览

1,里氏代换原则的示例

LSP讲的是基类和子类的关系。只有当这种关系存在时,里氏代换关系才存在。如果两个具体的类A,B之间的关系违反了LSP的设计,(假设是从B到A的继承关系)那么根据具体的情况可以在下面的两种重构方案中选择一种。-----创建一个新的抽象类C,作为两个具体类的超类,将A,B的共同行为移动到C中来解决问题。-----从B到A的继承关系改为委派关系。
在进行设计的时候,我们尽量从抽象类继承,而不是从具体类继承。如果从继承等级树来看,所有叶子节点应当是具体类,而所有的树枝节点应当是抽象类或者接口。当然这个只是一个一般性的指导原则,使用的时候还要具体情况具体分析。简单的理解为一个软件实体如果使用的是一个父类,那么一定适用于其子类,而且它察觉不出父类对象和子类对象的区别。也就是说,软件里面,把父类都替换成它的子类,程序的行为没有变化。

里氏代换原则的示例

2,继承的说话与里氏替换原则

在面向对象思想中可知,派生类拥有基类向下公开的所有特征,它是基类的一个特例。 当派生类对象赋于基类类型时,将出现以下情况:派生类的数据结构依次对应于基类的数据结构。而派生类拥有的自己的数据将不可见。 当基类的对象试图转换为派生类型时,将出现基类对象的数据无法依次填充完派生类的所有数据结构。这就造成了它将无法完成派生类定义的功能。编译器将会提示甚至报错。 这就是派生类能胜任基类功能,而基类却无法完全胜任派生类功能的原因。 强制转换属于 基类到派生的过程:那是因为 设计人员知道:该基类对象的数据结构完全可以填充完派生类的结构。否则,将出现强转错误。一般最好避免使用强转! 还有,子类能够出现在任何父类对象出现的地方不是完全正确的,父类有时也不会将自己的一些成员公开给子类。
也就是说基类所能提供的服务(所提供的功能)能够在自类中有所作用。 比如鸟基类和继承自他的燕子类,鸟类有飞行的方法,而燕子可以继承使用这个方法,他们就合适作为继承。 而鸵鸟就不适合继承自鸟,因为鸵鸟修改了他父类的功能,也就是屏蔽掉了。回答补充:面向对象设计的原则是这样的,并不是说一定,只不过如果子类会屏蔽或者修改父类行为,那么这种继承就不是一个好的设计而已。你当然可以把一个垃圾桶继承自水桶,但是水桶是放水的,而垃圾桶屏蔽了水桶的放水的功能而放垃圾了,当你使用多态特性的时候你会发现你有可能把水放在一个垃圾桶里面,这水还能喝么?

继承的说话与里氏替换原则

3,如何理解里氏替换原则

我简单的给你说一下吧。首先,这是编译器的要求,如果不这么做,无法通过编译。其次,面向对象的编程,其中继承有个大原则,任何子类的对象都可以当成父类的对象使用。如有父类人类,可以使用一般的枪,有警察类,可以使用任何的枪。class Person void shoot(SimpleGun simpleGun);}class Police extends Person void shoot(Gun gun);}其中SimpleGun extends Gun。这样的话任何警察类的对象都可以被当做人类来使用。也就是说警察类既然会使用任何的枪,当然可以使用一般的枪。Person person = new Police();person.shoot(simpleGun);而如果反过来,普通人可以使用任何抢,警察只能使用一般枪。class Person void shoot(Gun gun);}class Police extends Person void shoot(SimpleGun simpleGun);}这样的话就不合理了,既然警察是人类的一个子类,所以警察也是人类,既然是人类就应该能使用人类的方法,也就是使用任何的枪,可以根据上面的定义,反而警察类的能力还变小了。所以有一个原则,子类的能力必须大于等于父类,即父类可以使用的方法,子类都可以使用。返回值也是同样的道理。假设一个父类方法返回一个List,子类返回一个ArrayList,这当然可以。如果父类方法返回一个ArrayList,子类返回一个List,就说不通了。这里子类返回值的能力是比父类小的。还有抛出异常的情况。任何子类方法可以声明抛出父类方法声明异常的子类。而不能声明抛出父类没有声明的异常。这一切都是为了,任何子类的对象都可以当做父类使用。

如何理解里氏替换原则

4,C中基类和派生类之间的类型转换的内部原理是什么

里氏替换原则 即父类和派生类之间遵循 is a的关系。
有种叫做:里氏替换 原则,就是 基类和派生类的 转化 关系原理. 不想拷贝: http://baike.baidu.com/view/1688346.htm(直接去看看吧.应该懂些)
内部原理?不就是隐式转换吗 简单来说,派生类一定可以隐式转换为基类,因为派生类是继承基类过来的,所有基类有的定义它都会有,所以这样的隐式转换是被认为合法的,比如: class A class B:A A aInstance=new B(); 但是基类类型不能隐式转换为派生类,因为派生类中的成员定义在基类中是不一定存在的,如下面这样的转换是无法通过的: B bInstance=new A(); //不能从基类隐式转换到派生类 当你确实知道一个类型为A的变量实际上是派生类B时,可以通过强制类型转换为派生类: A a=new B(); .... .... B b=(B)a;
在类的层次结构中(即继承结构中)基类和派生类的构造函数的使用方式。派生类对象的初始化由基类和派生类共同完成:基类的成员由基类的构造函数初始化,派生类的成员由派生类的构造函数初始化。   当创建派生类的对象时,系统将会调用基类的构造函数和派生类的构造函数,构 造函数的执行次序是:先执行基类的构造函数,再执行派生类的构造函数。如果派生类又有对象成员,则,先执行基类的构造函数,再执行成员对象类的构造函数,最后执行派生类的构造函数。 至于执行基类的什么构造函数,缺省情况下是执行基类的无参构造函数,如果要执行基类的有参构造函数,则必须在派生类构造函数的成员初始化表中指出。如: class A public A( )  public A( int i ) }; class B : A public B( )  public B( int i )  public B( int i, int j ):A(i) }; B b1 = new B(); //执行基类A的构造函数A(),再执行派生类的构造函数B()B b2 = new B(1); //执行基类A的构造函数A(),再执行派生类的构造函数B(int)B b3 = new B(0,1); //执行执行基类A的构造函数A(int) ,再执行派生类的   构造函数B(int,int)   在这里构造函数的执行次序是一定要分析清楚的。另外,如果基类A中没有提供无参构造函数public A( ) class A public A( int i ) }; class B : A public B():A(i)  public B(int i):A(i)  public B(int i, int j):A(i) };
继承

5,C中基类和派生类之间的类型转换的内部原理是什么

内部原理?不就是隐式转换吗简单来说,派生类一定可以隐式转换为基类,因为派生类是继承基类过来的,所有基类有的定义它都会有,所以这样的隐式转换是被认为合法的,比如:class A { .... }class B:A {....} A aInstance=new B(); 但是基类类型不能隐式转换为派生类,因为派生类中的成员定义在基类中是不一定存在的,如下面这样的转换是无法通过的:B bInstance=new A(); //不能从基类隐式转换到派生类 当你确实知道一个类型为A的变量实际上是派生类B时,可以通过强制类型转换为派生类:A a=new B();........B b=(B)a;
<p>有种叫做:里氏替换 原则,就是 基类和派生类的 转化 关系原理.</p> <p> </p> <p>不想拷贝: <a href="http://wenwen.soso.com/z/urlalertpage.e?sp=shttp%3a%2f%2fbaike.baidu.com%2fview%2f1688346.htm" target="_blank">http://baike.baidu.com/view/1688346.htm</a></p>(直接去看看吧.应该懂些)
在类的层次结构中(即继承结构中)基类和派生类的构造函数的使用方式。派生类对象的初始化由基类和派生类共同完成:基类的成员由基类的构造函数初始化,派生类的成员由派生类的构造函数初始化。  当创建派生类的对象时,系统将会调用基类的构造函数和派生类的构造函数,构 造函数的执行次序是:先执行基类的构造函数,再执行派生类的构造函数。如果派生类又有对象成员,则,先执行基类的构造函数,再执行成员对象类的构造函数,最后执行派生类的构造函数。至于执行基类的什么构造函数,缺省情况下是执行基类的无参构造函数,如果要执行基类的有参构造函数,则必须在派生类构造函数的成员初始化表中指出。如:class A public A( )  public A( int i ) };class B : A public B( )  public B( int i )  public B( int i, int j ):A(i) };B b1 = new B(); //执行基类A的构造函数A(),再执行派生类的构造函数B()B b2 = new B(1); //执行基类A的构造函数A(),再执行派生类的构造函数B(int)B b3 = new B(0,1); //执行执行基类A的构造函数A(int) ,再执行派生类的   构造函数B(int,int)   在这里构造函数的执行次序是一定要分析清楚的。另外,如果基类A中没有提供无参构造函数public A( )  public A( int i ) };class B : A public B():A(i)  public B(int i):A(i)  public B(int i, int j):A(i) };

6,面向对象设计原则开放封闭原则

面向对象设计原则-开放封闭原则,对于扩展是开放的,对于修改是封闭的。修改(增加)类的成员变量或属性都是属于“修改”。扩展一般是指在原有的架构(小一点的说是接口)基础上进行扩展。开放封闭原则是指在现有的功能中,不修改原有的代码中进行扩展。为符合开放封闭原则,可以利用一些设计模式来实现。如第四副图,在原有countArea()方法需要增加输出功能。比如可以使用适配器模式(前提是要面向接口编程)。如下:原先的设计是定义一个接口ISqure,其定义的方法为第四副图左边类Squre包含的setLength、countArea方法。第四副图左边类Squre实现了ISqure。客户端调用代码:ISqure squre = new Square(); (一般不会这样直接获取对象,如通过工厂方法获取对象);double area = squre.countArea();以上是原有的设计现在需要countArea方法中还具有输出功能,如何在不修改Squre类的情况下做到呢?新建另一个类SqureImpl,同时它也实现接口ISqure,代码如下:public class SqureAdapter implements ISqure static ISqure squre = new Squre();//原有的代码中的类Squre public void setLength(double length) squre.setLength(length); } public double countArea() double area = squre.countArea(); System.out.println(area); //增加输出area return area; }}修改客户端调用代码:ISqure squre = new SqureAdapter(); double area = squre.countArea();这样达到了不修改原有Square类,而是通过继承(扩展)接口ISqure,来增加了输出area的功能。这样做的好处是维持了原有代码(功能)的稳定性(可能系统的代码其他地方有很多调用Square的countArea方法,这样对它们是不影响的)。我也是最近在看面向对象设计原则的书,有问题或建议请提出来,大家共同学习。
1,面向对象是一种思考方式(不用考虑哪些定义,就像我问你,汉语的说话方式,大部分人是不会思考完你要说的话是否符合规则在说呢,只要记住把所有涉及到的东西看成对象去编程)例:“一个人吃饭” 面向过程的思考方式:“第一步,人拿起筷子。第二步,人用筷子夹饭。第三步,人把饭吃掉。第四步,无线循环第二步第三步,直到饭没或人吃饱。” 面向对象的思考方式:人是一个类,饭是一个类,饭类中某属性减少,人类中某属性增加,饭类中属性没有时,或人类中属性达到最大值即吃完。 扩展还是修改? 扩展时什么?不就是增加,往类里面添加就是扩展。其实答案你自己已经写出来了,你 1,2,3,4,里面那个有添加就是扩展。修改不就是改变,改为嘛。扩展是开放的,对于修改是封闭的。就是说 扩展你可以无限扩,没有局限。 修改你只能改那类里的东西,类本来就有的属性。(没必要记,有些人就喜欢把不需要定义的,硬改成有定义。只要记住把所有涉及到的东西看成对象去编程)
1、开闭原则(Open Close Principle):开闭原则就是说对扩展开放,对修改关闭。-----在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果--------。所以一句话概括就是:为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类。看下定义:这样的原则还有很多:2、里氏代换原则(Liskov Substitution Principle)里氏代换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一。 里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。 LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。里氏代换原则是对“开-闭”原则的补充。实现“开-闭”原则的关键步骤就是抽象化。而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范3、依赖倒转原则(Dependence Inversion Principle)这个是开闭原则的基础,具体内容:真对接口编程,依赖于抽象而不依赖于具体。4、接口隔离原则(Interface Segregation Principle)这个原则的意思是:使用多个隔离的接口,比使用单个接口要好。还是一个降低类之间的耦合度的意思,从这儿我们看出,其实设计模式就是一个软件的设计思想,从大型软件架构出发,为了升级和维护方便。所以上文中多次出现:降低依赖,降低耦合。5、迪米特法则(最少知道原则)(Demeter Principle)为什么叫最少知道原则,就是说:一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。6、合成复用原则(Composite Reuse Principle)原则是尽量使用合成/聚合的方式,而不是使用继承。

文章TAG:里氏  代换  原则  示例  里氏代换原则  
下一篇