05继承与多态

一、 继承条件下的构造方法调用

1、运行 TestInherits.java 示例,观察输出,注意总结父类与子类之间构造方法的调用关系修改Parent构造方法的代码,显式调用GrandParent的另一个构造函数,注意这句调用代码是否是第一句,影响重大!

源代码:

 

package lianxi7;

 

class GrandParent

{

 

    public GrandParent()

    {

        System.out.println("GrandParent Created");

    }

 

    public GrandParent(String string)

    {

        System.out.println("GrandParent Created.String:"+string);

    }

 

}

 

class Parent extends GrandParent{

    public Parent(){

        super("sdg");

        

        System.out.println("Parent Created");

        

    }

}

 

class Child extends Parent{

    public Child(){

        

        System.out.println("Child Created");

    }

}

public class TestInherits {

 

    public static void main(String[] args) {

        // TODO Auto-generated method stub

        

        Child c=new Child();

    }

}

 

实验结果截图:

 

 

结论:通过 super 调用基类构造方法,必须是子类构造方法中的第一个语句,必须写在第一个。

2、为什么子类的构造方法在运行之前,必须调用父类的构造方法?能不能反过来?为什么不能反过来?

子类是通过父类继承过来的,所以子类有父类的属性和方法,如果不调用父类的构造方法,那么怎么初始化父类中定义的属性,即怎么给父类的属性分配内存空间 ,如果父类的属性没有分配内存空间,那么子类访问父类的属性,就会报错。

二、神奇的“+”

 

注意最后一句,一个字串和一个对象相加,得到以下结果:

 

“+”运算中,当任何一个对象与一个String对象,连接时,会隐式地调用其toString()方法,默认情况下,此方法返回类名 @ + hashCode”。为了返回有意义的信息,子类可以重写toString()方法。

三、请自行编写代码测试以下特性: 在子类中,若要调用父类中被覆盖的方法,可以使用super关键字。

源代码:

 

class GrandParent

{

 

    public GrandParent()

    {

        System.out.println("GrandParent Created");

    }

 

    public GrandParent(String string)

    {

        System.out.println("GrandParent Created.String:"+string);

    }

 

}

 

class Parent extends GrandParent{

    public Parent(){

        super("sdg");

        

        System.out.println("Parent Created");

        

    }

}

 

class Child extends Parent{

    public Child(){

        

        System.out.println("Child Created");

    }

}

public class TestInherits {

 

    public static void main(String[] args) {

        // TODO Auto-generated method stub

        

        Child c=new Child();

    }

}

 

实验截图为:

 

未添加super("sdg")之前的结果:

 

课后作业一:接口多态:使用接口代替抽象基类
一、源代码
package zoo4;

 

import java.util.Vector;

 

public class Zoo2 {

 

    public static void main(String args[]) {

        Feeder f = new Feeder("小李");

        Vector<Animal> ans = new Vector<Animal>();//可随时向其中加入或移除对象

 

        //饲养员小李喂养一只狮子

        ans.add(new Lion());

        //饲养员小李喂养十只猴子

        for (int i = 0; i < 10; i++) {

            ans.add(new Monkey());

        }

        //饲养员小李喂养5只鸽子

        for (int i = 0; i < 5; i++) {

            ans.add(new Pigeon());

        }

        f.feedAnimals(ans);

    }

}

 

class Feeder {

 

    public String name;

 

    Feeder(String name) {

        this.name = name;

    }

 

    public void feedAnimals(Vector<Animal> ans) {

        for (Animal an : ans) {

            an.eat();

        }

    }

}

 

interface Animal {

 

    public void eat();

}

 

class Lion implements Animal {

 

    public void eat() {

        System.out.println("我不吃肉谁敢吃肉!");

    }

}

 

class Monkey implements Animal {

 

    public void eat() {

        System.out.println("我什么都吃,尤其喜欢香蕉。");

    }

}

 

class Pigeon implements Animal {

 

    public void eat() {

        System.out.println("我要减肥,所以每天只吃一点大米。");

    }

}

 

二、实验运行截图

 

 

验证:

①TestInstanceof.java

代码

 

 public class TestInstanceof

{

    public static void main(String[] args) 

    {

        //声明hello时使用Object类,则hello的编译类型是Object,Object是所有类的父类

        //但hello变量的实际类型是String

        Object hello = "Hello";

        //String是Object类的子类,所以返回true。

        System.out.println("字符串是否是Object类的实例:" + (hello instanceof Object));

        //返回true。

        System.out.println("字符串是否是String类的实例:" + (hello instanceof String));

        //返回false。

        System.out.println("字符串是否是Math类的实例:" + (hello instanceof Math));

        //String实现了Comparable接口,所以返回true。

        System.out.println("字符串是否是Comparable接口的实例:" + (hello instanceof Comparable));

        String a = "Hello";

        //String类既不是Math类,也不是Math类的父类,所以下面代码编译无法通过

        //System.out.println("字符串是否是Math类的实例:" + (a instanceof Math));

    }

}

 

运行结果截图:

 

②TestCast.java

代码如下:

 

 

class Mammal{}

class Dog extends Mammal {}

class Cat extends Mammal{}

 

public class TestCast

{

    public static void main(String args[])

    {

        Mammal m;

        Dog d=new Dog();

        Cat c=new Cat();

        m=d;

        //d=m;

        d=(Dog)m;

        //d=c;

        //c=(Cat)m;

 

    }

}

 

 

 

运行结果没有出错!

③Zoo.java

代码如下:

 

 

package zoo4;

 

import java.util.Vector;

 

public class Zoo {

 

    public static void main(String args[]) {

        Feeder f = new Feeder("小李");

        Vector<Animal> ans = new Vector<Animal>();//可随时向其中加入或移除对象

 

        //饲养员小李喂养一只狮子

        ans.add(new Lion());

        //饲养员小李喂养十只猴子

        for (int i = 0; i < 10; i++) {

            ans.add(new Monkey());

        }

        //饲养员小李喂养5只鸽子

        for (int i = 0; i < 5; i++) {

            ans.add(new Pigeon());

        }

        f.feedAnimals(ans);

    }

}

 

class Feeder {

 

    public String name;

 

    Feeder(String name) {

        this.name = name;

    }

 

    public void feedAnimals(Vector<Animal> ans) {

        for (Animal an : ans) {

            an.eat();

        }

    }

}

 

abstract class Animal {

 

    public abstract void eat();

}

 

class Lion extends Animal {

 

    public void eat() {

        System.out.println("我不吃肉谁敢吃肉!");

    }

}

 

class Monkey extends Animal {

 

    public void eat() {

        System.out.println("我什么都吃,尤其喜欢香蕉。");

    }

}

 

class Pigeon extends Animal {

 

    public void eat() {

        System.out.println("我要减肥,所以每天只吃一点大米。");

    }

}

 

 

 

运行结果截图:

 

 

原文地址:https://www.cnblogs.com/zhangfan0801/p/7813762.html