房产中介网站建设进度,事件营销的类型,本地wordpress搭建,做网站需求文档向上转型#xff1a;子类对象转为父类#xff0c;父类可以是接口。公式#xff1a;Father f new Son();Father是父类或接口#xff0c;son是子类。向下转型#xff1a;父类对象转为子类。公式#xff1a;Son s (Son)f;我们将形参设为父类Animal类型#xff0c;当执行t…向上转型子类对象转为父类父类可以是接口。公式Father f new Son();Father是父类或接口son是子类。向下转型父类对象转为子类。公式Son s (Son)f;我们将形参设为父类Animal类型当执行test.f(c)时内存情况如下图c作为Cat类型传入Animal a作为形参相当于执行了Animal a new Cat()这时a和c同时指向Cat对象但此时a不能访问Cat类扩展的数据成员所以再将a强转成Cat类型即可。如果不存在这样的转型机制则针对猫和狗我们还要分别写两个函数f(Cat c)和f(Dog d)。但其实上图程序的可扩展性也不是最好的。我们还可以利用动态绑定(即多态)将扩展性进一步提升。多态机制的三个前提分别是(1)要有继承(2)要重写即子类对父类中某些方法进行重新定义(3)要向上转型用父类引用指向子类对象。下面来看一个例子class Animal { private String name; /*** 在Animal类自定义的构造方法* param name */Animal(String name) { this.name name;} /*** 在Animal类里面自定义一个方法enjoy */public void enjoy() {System.out.println(动物的叫声……);}}class Cat extends Animal { private String eyesColor; /*** 在子类Cat里面定义Cat类的构造方法* param n* param c */Cat(String n, String c) { /*** 在构造方法的实现里面首先使用super调用父类Animal的构造方法Animal(String name)。* 把子类对象里面的父类对象先造出来。 */super(n);eyesColor c;} /*** 子类Cat对从父类Animal继承下来的enjoy方法不满意在这里重写了enjoy方法。 */public void enjoy() {System.out.println(我养的猫高兴地叫了一声……);}}/*** 子类Dog从父类Animal继承下来Dog类拥有了Animal类所有的属性和方法。* author gacl* */class Dog extends Animal { /*** 在子类Dog里面定义自己的私有成员变量 */private String furColor; /*** 在子类Dog里面定义Dog类的构造方法* param n* param c */Dog(String n, String c) { /*** 在构造方法的实现里面首先使用super调用父类Animal的构造方法Animal(String name)。* 把子类对象里面的父类对象先造出来。 */super(n);furColor c;} /*** 子类Dog对从父类Animal继承下来的enjoy方法不满意在这里重写了enjoy方法。 */public void enjoy() {System.out.println(我养的狗高兴地叫了一声……);}}/*** 子类Bird从父类Animal继承下来Bird类拥有Animal类所有的属性和方法* author gacl* */class Bird extends Animal { /*** 在子类Bird里面定义Bird类的构造方法 */Bird() { /*** 在构造方法的实现里面首先使用super调用父类Animal的构造方法Animal(String name)。* 把子类对象里面的父类对象先造出来。 */super(bird);} /*** 子类Bird对从父类Animal继承下来的enjoy方法不满意在这里重写了enjoy方法。 */public void enjoy() {System.out.println(我养的鸟高兴地叫了一声……);}}/*** 定义一个类Lady(女士)* author gacl* */class Lady { /*** 定义Lady类的私有成员变量name和pet */private String name; private Animal pet; /*** 在Lady类里面定义自己的构造方法Lady()* 这个构造方法有两个参数分别为String类型的name和Animal类型的pet* 这里的第二个参数设置成Animal类型可以给我们的程序带来最大的灵活性* 因为作为养宠物来说可以养猫养狗养鸟只要是你喜欢的都可以养* 因此把它设置为父类对象的引用最为灵活。* 因为这个Animal类型的参数是父类对象的引用类型因此当我们传参数的时候* 可以把这个父类的子类对象传过去即传Dog、Cat和Bird等都可以。* param name* param pet */Lady(String name, Animal pet) { this.name name; this.pet pet;} /*** 在Lady类里面自定义一个方法myPetEnjoy()* 方法体内是让Lady对象养的宠物自己调用自己的enjoy()方法发出自己的叫声。 */public void myPetEnjoy() {pet.enjoy();}}public class Jerque { public static void main(String args[]) { /*** 在堆内存里面new了一只蓝猫对象出来这个蓝猫对象里面包含有一个父类对象Animal。 */Cat c new Cat(Catname, blue); /*** 在堆内存里面new了一只黑狗对象出来这个黑狗对象里面包含有一个父类对象Animal。 */Dog d new Dog(Dogname, black); /*** 在堆内存里面new了一只小鸟对象出来这个小鸟对象里面包含有一个父类对象Animal。 */Bird b new Bird(); /*** 在堆内存里面new出来3个小姑娘名字分别是l1l2l3。* l1养了一只宠物是c(Cat)l2养了一只宠物是d(Dog)l3养了一只宠物是b(Bird)。* 注意调用Lady类的构造方法时传递过来的cdb是当成Animal来传递的* 因此使用cdb这三个引用对象只能访问父类Animal里面的enjoy()方法。 */Lady l1 new Lady(l1, c);Lady l2 new Lady(l2, d);Lady l3 new Lady(l3, b); /*** 这三个小姑娘都调用myPetEnjoy()方法使自己养的宠物高兴地叫起来。 */l1.myPetEnjoy();l2.myPetEnjoy();l3.myPetEnjoy();}}上面的例子中我们发现如果我们想要加入新的动物只需定义相应的类继承Animal完全不用动任何一处代码因为这里运用了面向对象最核心的东西——多态。与之前的例子不同虽然我们一直强调当用父类的引用指向子类对象父类无法访问子类自己的成员但是方法与数据成员不同具体调哪一个方法是等到运行时决定的new出了什么对象就调用相应对象的方法取决于实际new出的对象而不是指向对象的引用所以当传入不同动物类型mypetEnjoy()就会去执行不同的方法