(第25讲)java中的多态的深入理解

来源:互联网 发布:dnf数据出现异常 编辑:程序博客网 时间:2024/06/05 09:53


多态通俗的讲:是指父类的引用指向 了子类的对象;

比如:Animal(动物)类,Dog(狗),狗属于动物,所以Dog extends Animal
一般Animal animal = new Dog(); 父类的引用animal指向子类对象Dog();就属于多态,


1、对于Java中的多态是编译看左边,运行看右边,方法在调用的时候会出现两种情况,一种是重载,另一种是子类重写(静态方法是不可以被重写的)

即 编译器是根据引用类型来判断有哪些method可以调用,而不是根据Object的类型。

比如Animal animal = new Dog();会根据animal来判断什么方法可以用,然后再看右边的类型中这个方法是否被覆盖,若被覆盖用已经重写了的方法。

2、JAVA静态方法形式上可以重写,但从本质上来说不是JAVA的重写。因为静态方法只与类相关,不与具体实现相关,声明的是什么类,则引用相应类的静态方法(本来静态无需声明,可以直接引用),因此静态方法的调用只用看引用就行,即只看左边;

3、概括的说重载主要看传入参数的左边类型,重写调用时候如果存在重载,则首先根据左边类型看参数调用对应方法,然后再根据调用者的实际类型处理。

class A1 {

    public String show(D1 obj) {        return ("A1 and D1");    }

    public String show(A1 obj) {        return ("A1 and A1");    }
}

class B1 extends A1 {
    public String show(B1 obj) {        return ("B1 and B1");    }//重载

    public String show(A1 obj) {        return ("B1 and A1");    }//覆盖(重写)
}

class C1 extends B1 {}

class D1 extends B1 {}


public class Duotai3 {

    public static void main(String[] args) {
        A1 a1 = new A1();
        A1 a2 = new B1();
        A1 a3 = new C1();
        A1 a4 = new D1();
        System.out.println(a1.getClass());
        System.out.println(a2.getClass());
        System.out.println(a3.getClass());
        System.out.println(a4.getClass());
        System.out.println("_______________________");
        B1 b1 = new B1();
        B1 b2 = new C1();
        B1 b3 = new D1();

        A1 ab = (A1)b1; System.out.println("ab==b1: "+(ab==b1));//true,所以如果调用 ab 的方法,调用的其实是 B1类中 的方法

        System.out.println(b1.getClass());
        System.out.println(b2.getClass());
        System.out.println(b3.getClass());  
        System.out.println(ab.getClass());
        System.out.println("_______________________");
        C1 c1 = new C1();
        A1 ac = (A1)c1; System.out.println("ac==c1: "+(ac==c1));//true所以如果调用 ac 的方法,调用的其实是 C1类中 的方法
        B1 bc = (B1)c1;System.out.println("bc==c1: "+(bc==c1));//true所以如果调用 bc  的方法,调用的其实是 C1类中 的方法
        System.out.println(c1.getClass());
        System.out.println(ac.getClass());
        System.out.println(bc.getClass());
        System.out.println("_______________________");
        D1 d1 = new D1();
        A1 ad = (A1)d1;  System.out.println("ad==d1: "+(ad==d1));//true所以如果调用 ad 的方法,调用的其实是 D1类中 的方法
        B1 bd = (B1)d1;  System.out.println("bd==d1: "+(bd==d1));//true所以如果调用 bd 的方法,调用的其实是 D1类中 的方法
        System.out.println(d1.getClass());
        System.out.println(ad.getClass());
        System.out.println(bd.getClass());
        System.out.println("_______________________");
        
    }

}

结果是:

class com.my.A1
class com.my.B1
class com.my.C1
class com.my.D1
_______________________
ab==b1: true
class com.my.B1
class com.my.C1
class com.my.D1
class com.my.B1
_______________________
ac==c1: true
bc==c1: true
class com.my.C1
class com.my.C1
class com.my.C1
_______________________
ad==d1: true
bd==d1: true
class com.my.D1
class com.my.D1
class com.my.D1
_______________________



 
public class Duotai1 {

    public static void main(String[] args) {
        A1 a1 = new A1();
        A1 a2 = new B1(); //a2其实是B1类
        B1 b = new B1();
        C1 c = new C1();
        D1 d = new D1();  
        System.out.println(a1.show(b));//A A
        System.out.println(a1.show(c)); //A A
        System.out.println(a1.show(d));//A D
        
        System.out.println(a2.show(b)); //B A这里是因为首先看左边,是A1类,调用show(A1 obj),但是运行时发现是B1类,调用重写的show(A1 obj) { return ("B1 andA1"); }
        System.out.println(a2.show(c)); //B A
        System.out.println(a2.show(d));//A D这里是因为B1中没有重写show(D1 obj),所以调用父类的show(D1 obj)
        
        System.out.println(b.show(b)); //B B这里是因为左边右边都是B1类,直接调用B1中的show(B1 obj)
        System.out.println(b.show(c)); //B B
        System.out.println(b.show(d));//A D
    }

}

 结果是:

A1 and A1
A1 and A1
A1 and D1
B1 and A1
B1 and A1
A1 and D1
B1 and B1
B1 and B1
A1 and D1

 

public class Duotai2 {

    public static void main(String[] args) {
            B b1 = new B();
            b1.print();
            A a1 = (A)b1;
            System.out.println("a1==b1:"+(a1==b1)+"; a1.equals(b1):"+(a1.equals(b1)));//true true
            a1.print(); //classB    a1实际上是B1类,所以会直接调用B1中覆盖的方法
            A a3 = new B();
            System.out.println("a3==a1:"+(a3==a1)+"; a3.equals(a1):"+(a3.equals(a1)));//false false
            a3.print(); //classB    a3实际上是B1类,所以会直接调用B1中覆盖的方法
            A a2 = new A();
            a2.print();
            //B b2 = (B)a2;错误的
            //b2.print();
        }
    }
    class A{
        public void print(){
            System.out.println("classA");
        }
    }
    class B extends A{
        public void print(){
            System.out.println("classB");
        }
    }
结果是:
classB
a1==b1:true; a1.equals(b1):true
classB
a3==a1:false; a3.equals(a1):false
classB
classA

package com.my;

public class Duotai3 {

    public static void main(String[] args) {
        Father f1 = new Father();
        Father f2 = new Child();
        Child c1 = new Child();
        System.out.println("___________name_____________");
        System.out.println(f1.getName());// Father
        System.out.println(f2.getName());// Father因为只用看引用,即左边的就行了,可以看出是Father 类,所以调用Father 类中的getName()
        System.out.println(c1.getName());// Child  
        System.out.println("___________age_____________");
        System.out.println(f1.getAge());// 34
        System.out.println(f2.getAge());// 14
        System.out.println(c1.getAge());// 14
    }

}
  class Father{
      public static String getName(){
          return "Father";
      }
      public int getAge(){
          return 34;
      }
  }
  class Child extends Father{
      public static String getName(){
          return "Child";
      }
      public int getAge(){
          return 14;
      }
  }

结果是:

___________name_____________
Father
Father
Child
___________age_____________
34
14
14



0 0
原创粉丝点击