012.继承的细节,向上转型 、向下转型

1.查看下面的代码有啥不一样的地方?试着运行一下查看一下结果吧。

package com.qx.test;

public class A {
    int age = 20 ;
     void test()
     {
         System.out.println(age);
     }
}

class B extends  A
{
    int age = 22;

    void test()
    {
        System.out.println(age);
    }
}

class B extends  A
{
    int age = 22;

    void test()
    {
       super.test();
    }
}

2.向上转型:栈内存的票是父类的类型

(1)向上转型的代码:

package com.qx.jicheng;

public class A
{
    int age = 20;

    void test()
    {
        System.out.println(age);
    }
}
package com.qx.jicheng;

public class B  extends A{
    int age = 22;

    void test()
    {
        System.out.println(age);
    }
}
package com.qx.jicheng;

public class Entrance {
    public static void main(String[] args) {
        A a = new B();
        a.test();
    }
}

 

(2)向上转型的特点

①对于成员方法

父类寻找这个方法(再次强调是通过方法名称和参数列表)

a.若这个方法父类不存在,则不能通过编译。

b.若这个方法父类存在,则访问的是子类的方法。

 

package com.qx.jicheng;

public class A
{
    int age = 20;

    void test()
    {
        System.out.println("test++++A");
    }
}
package com.qx.jicheng;

public class B  extends A{
    int age = 22;

    void test()
    {
        System.out.println("test++++B");
    }

    void test1()
    {
        System.out.println("test1++++B");
    }
}
package com.qx.jicheng;

public class Entrance {
    public static void main(String[] args) {
        A a = new B();
        a.test1();
    }
}

 

②对于成员变量

a.父类不存在这个成员变量,则不能通过编译

b.仅仅能访问到父类的成员变量!

package com.qx.jicheng;

public class A
{
    int age = 20;

    void test()
    {
        System.out.println("test++++A");
    }


}
package com.qx.jicheng;

public class B  extends A{
    int age = 22;

    void test()
    {
        System.out.println("test++++B");
    }

}
package com.qx.jicheng;

public class Entrance {
    public static void main(String[] args) {
       B b = new B();
       test(b);
        /**
         * B b =new B()
         * test(b)
         * 上述代码等价与
         * C c = new C()
         * test(c)
         */
    }

    static void test(A a)
    {
        /**
         * 1: a.可以找到的方法有a.test()、a.age
         * 2. 如果放进去的是b类型的会有 A a = b;
         * 3. a.test()如果调用test方法,一定调用的是b的test方法
         * 4. 默认会有一个向上转型
         * 5. 如果是A-->B-->C这种情况实际上,
         */
        a.test();
    }
}

方法参数列表中的向上转型(特点同上面两点)

(若存在方法的重载,并且重载后的方法参数列表都是父类,则选取结构图中最近的方法调用)

package com.qx.jicheng;

public class A
{
    int age = 20;

    void test()
    {
        System.out.println("test++++A");
    }


}
package com.qx.jicheng;

public class B  extends A{
    int age = 22;

    void test()
    {
        System.out.println("test++++B");
    }

}
package com.qx.jicheng;

public class C extends B{
}
package com.qx.jicheng;

/**
 * A-->B-->C
 */
public class Entrance {
    public static void main(String[] args) {
       C  c= new C();
       test1(c);//这里最后会调用起

    }

    static void test1(A a)
    {
        a.test();
    }

    static void test1(B b)
    {
        //调用这里哦

    }
}

3.向下转型

当我们用子类的凭证去指向父类的凭证时,就叫做向下转型.

class A

class B extends A             

class C extends A

 

B类是子类,A类是父类.

对于B,如果我们想使用B. 则正常的实例化过程如下:
B b=new B();

向下转型表示如下:

B b=new B();

A a=b;

B b=(B)a;

 

注意:向下转型可能会产生运行时的错误: A-->B-->C或者A-->B 、 A-->C

C c=new C();

A a=c;

B b=(B)a;

一般向下转型正确的话:

一定经历了向上转型

转型到的可以是对象的真实类型或者对象的父类(一个对象真正的类型是它自己本身的类)

 

 

向下转型的特点

①可能会产生运行时的错误(编译不会报错)

②向下转型并不一定会转到真正的类型上,如果仍然转到的是一个父类。则遵从我们上面所说的向上转型的特点.

如果没有报错,对于转型后的访问和正常申明后(可能也涉及到向上转型)的访问没有区别

 

避免向下转型报错的办法

使用instanceof 关键字

关键字介绍:判断 对象 是不是 该类的子类或者本身

举例: a instance of A a是否是A类本身或者是A类的子类.

②具体使用:利用instanceof 判断后,进行向下转型从而使用子类特有的方法.

 

posted @ 2022-04-05 11:10  李林林  阅读(58)  评论(0编辑  收藏  举报