zoukankan      html  css  js  c++  java
  • 动手动脑——继承与多态

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

    class Grandparent {
        Grandparent(){
        System.out.println("GrandParent Created.");
        }
        Grandparent(String string) {
            System.out.println("GrandParent Created.String:" + string);
        }
    
    }
    class Parent extends Grandparent{
        Parent(){
            //super("Hello.Grandparent.");
            System.out.println("Parent Created");
            //super("Hello.Grandparent.");
        }
    }
    class Child extends Parent {
        Child(){
            System.out.println("Child Created");
        }
    }
    public class TestInherits {
        public static void main(String args[]){
            Child c = new Child();
        }
    }

      上述程序中主方法只创建了一个Child类的对象,在对象创建时默认使用了super()方法调用父类的无参构造方法。若是只将第一个//super("Hello.Grandparent.");解注释,则运行结果中第一行会变成GrandParent Created.String:Hello.Grandparent.。而只将第二个解注释,则编译器会报错。所以,通过 super 调用基类构造方法,必须是子类构造方法中的第一个语句。

    类型转换问题

    class Mammal{}
    class Dog extends Mammal {}
    class Cat extends Mammal{}
    class Test {
        public static void main(String[] args) {
            Mammal m=null;
            Dog d=new Dog();
            Cat c=new Cat();
            m=d;
            d=m;       //×
            d=(Dog)m;
            d=c;       //×
            c=(Cat)m;
        }
    }

      子类对象可以直接赋给基类变量。 基类对象要赋给子类对象变量,必须执行类型转换, 其语法是: 子类对象变量=(子类名)基类对象名; 如果类型转换失败,Java会抛出ClassCastException异常。

      可以使用instanceof运算符判断一个对象是否可以转换为指定的类型: Object obj="Hello"; if(obj instanceof String) System.out.println("obj对象可以被转换为字符串");

    public class ParentChildTest {
        public static void main(String[] args) {
            Parent parent=new Parent();
            parent.printValue();//100
            Child child=new Child();
            child.printValue();//200
            
            parent=child;
            parent.printValue();//200
            
            parent.myValue++;
    System.out.println(parent.myValue); parent.printValue();
    //200 ((Child)parent).myValue++; parent.printValue();//201 } } class Parent{ public int myValue=100; public void printValue() { System.out.println("Parent.printValue(),myValue="+myValue); } } class Child extends Parent{ public int myValue=200; public void printValue() { System.out.println("Child.printValue(),myValue="+myValue); } }

      上述程序中,主方法中存在将子类对象赋给基类对象,所以会出现明明调用的基类对象的方法,运行结果中却变成了调用子类对象的方法的情况。将子类对象赋给基类对象过后,又出现了parent.myValue++;这一句,实际上这一句是将基类对象的myValue值加一(由后边输出基类对象的myValue值可以看出),但由于基类对象此时为子类型,所以调用的方法并不是基类对象自己的方法,因此会出现结果截图中第五行所示的情况。((Child)parent).myValue++;这一句中,由于将基类对象强制转换为子类型再进行加法运算,所以实际上是子类对象的myValue值加一。

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

  • 相关阅读:
    [zz]struct epoll_event
    [zz]libev 简介
    [zz]红黑树
    [zz]leveldb 实现原理
    [zz]使用 libevent 和 libev 提高网络应用性能
    [zz]AVL树
    [zz]do...while(0)的妙用
    Mybatis中的缓存简介
    Spring框架的介绍
    ThreadLocal
  • 原文地址:https://www.cnblogs.com/dream0-0/p/9925136.html
Copyright © 2011-2022 走看看