06 继承与多态

    

  1. 动手实验

        

  因为子类继承于父类,构造方法相当于对象初始化,只有父类先完成初始化,子类对象才能执行自己的初始化。子类在进行初始化的时候会默认调用父类的构造,所以不能反过来。

     2 动手动脑

 

       

        代码:

 1 package Parent_son;
 2 class Parent
 3 {
 4     public int value=100;
 5     
 6     public void Introduce()
 7     {
 8 
 9             System.out.println("I'm father");
10 
11         }
12 }
13 class Son extends Parent
14 {
15 
16     public int value=101;
17 
18          public void Introduce()
19     {
20             super.Introduce();
21              System.out.println("I'm Parent"+ super.value);
22             System.out.println("I'm son");
23     }
24 }
25 public class JiCheng1 {
26 
27     public static void main(String[] args) {
28           Son p=new Son();
29             p.Introduce();
30             System.out.println(p.value);
31 
32     }
33 }

 

 

结果截图:

 

3.子类与父类间的类型转换

     

 

                            

 

                  d=m,d=c,c=(Cat)m不能运行

     m=d,子类对象可以直接赋给基类变量,因为子类是对父类的一个改动,有父类里的所有的变量。

  1.

    如果父类对象与引用指向的实际是一个子类对象,那么调用这个方法时,可以使用子类对象作为实际参数。

  2.

    类型转换必须在继承层次类转换,即超类与子类间。d=m因为父类里面不一定包含全部子类所有的变量,基类对象要赋给子类对象变量,必须执行类型转换,d=(Dog)m所示。

  3.

    d=c兄弟类间不存在继承,因此也不存在类型转换。 

  4.

    对象的赋值是地址标识的传递,即两个对象名共同使用同一段内存地址。

  5.

     c=(Cat)m中不显示错误,会抛出异常,相当于“子=(子)父”如果父类变量引用的是正确的子类型(即父类对象要想类型转换后赋给子类对象,其本身引用的是子类型的内存空间),赋值将执行,如果父类变量引用的是不相关的子类型,将会生成class CastException异常。

 

4. 同名函数的处理

          

 

  1.   上面的程序运行结果是什么?

           

             2.  你如何解释会得到这样的输出?

 

    子类对象可以赋值给父类,子类可以覆盖父类,但是父类中的变量的值是不会变化的,访问父类中的变量中的变量时,可以用super关键词来访问。parent.printValue()的方法实际会调用child.printValue()方法(因为此时的parent引用child),即引用对象后,调用parent.printValue()即引用对象将原来父类的方法在child子类中重写了,父类被覆盖时,如果子类被当做父类使用,则通过子类访问的字段是父类的!对父类中的变量进行操作时,parent.myValue++父类中的变量改变,子类的属性不变,因为此时仍然使用的是子类的方法,所以输出子类的属性。

    ((Child)parent).myValue++;

    将parent强制转换为Child类型,所以操作属性为子类的,所以输出结果为:201 

           3  计算机是不会出错的,之所以得到这样的运行结果也是有原因的,那么从这些运行结果中,你能总结出Java的哪些语法特性?

 

    当子类与父类拥有一样的方法,并且让一个父类变量引用一个子类对象时,到底调用哪个方法,由对象自己的“真实”类型所决定,这就是说:对象是子类型的,它就调用子类型的方法,是父类型的,它就调用父类型的方法。如果子类与父类具有相同的字段,则,子类中的字段会代替会隐藏父类的字段,子类方法中访问的是子类的字段(而非父类中的字段)。如果子类方法确实相访问父类中被隐藏的同名字段,可以用super关键词来访问。

    父类的引用可以调用父类中定义所有属性与方法,对于子类中定义而父类中没有的属性与方法,父类引用无法调用。子类重定义父类已有的属性,父类引用的还是本类的属性值。子类重定义父类已有方法时,父类引用调用的是子类重写过的方法。

    而父类赋值给子类必须经过子类强制转换,此时的对象已是子类对象,对象操作的属性,方法是子类的。

 

5.接口

        

 

  能否把“会游泳”、“能被吃”这种特性独立出来作为一种“可选项”,可以被“附加”到具体对象上?

  在面向对象世界中,可以使用“接口(interface)”来抽象对象的行为特性。定义一个接口,采用关键字interface,实现一个接口,采用关键字implements接口的成员函数自动成为public的,数据成员自动成为 staticfinal的。如果接口不声明为public的,则自动变为package

  一个类可以同时实现多个接口。

  可以通过继承接口来扩充已有接口,并形成一个新的接口。

        interface OneInterface {

  void f1();

  }

  interface TwoInterface extends OneInterface {

  void f2();

  }

  实现子接口的类,必须实现“父”“子”接口所定义的所有方法,才能被实例化(即new出一个对象)接口也可定义常量,

  public interface ArrayBound {

  public static final int LOWBOUND=1;

  public static final int UPBOUND=100;

  }

  只要一个类声明实现了这个接口,就可以直接使用这些常量名

  注意:定义在接口中的常量必须被初始化。

实例:

 1 package 测试1;
 2  interface  Food
 3 {
 4     public void Cook();
 5 }
 6  interface  Swim
 7 {
 8     public void swim();
 9 }
10 class Bird
11 {
12     public void show() {
13         System.out.println("Duck is a bird");
14     }
15 }
16  class Duck extends Bird implements Swim,Food
17 {
18     public void Cook() {
19         System.out.println("Duck can be cooked");
20     }
21     public void swim() {
22         System.out.println("Duck can swim");
23         
24     }
25 }
26 public class Anaimal {
27     public static void main(String[] args) {
28         Food f = new Duck();//接口类型  接口类型的变量=new 实现了接口的具体类型()
29         Swim s=new Duck();
30         s.swim();
31         f.Cook();
32     
33     }
34 
35 }

结果截图:

 

 

 

原文地址:https://www.cnblogs.com/zhao-teng-ass/p/7812110.html