zoukankan      html  css  js  c++  java
  • Java——类的继承与多态

    1. 在子类中,若要调用父类中被覆盖的方法,可以使用super关键字。

    以以下代码为例解释:

    package homework;

     

    class Grandfather{

           public Grandfather(){

                  System.out.println("Grandfather created. ");

           }

    }

    class TestParent extends Grandfather{

           public TestParent(){

                  System.out.println("Father  created. ");

           }

          

           public void show() {

                  System.out.println("This is father's words ");

           }

          

    }

     

    class TestChild extends TestParent{

     

           public TestChild(){

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

           }

            

           public void show() {

                  super.show();

                  System.out.println("This is my words ");

           }

          

    }

    public class TestClassP_C {

     

           public static void main(String[] args) {

                  // TODO Auto-generated method stub

                 

                  TestChild c=new TestChild();

                  //依次继承

                  c.show();

                  //调用TestChild中show()函数,由于函数中有super,因此调用父类中被覆盖的show()方法

           }

     

    }

    (1)关于子类的创建:

    若父类及父类的父类有默认构造函数,则从最底层(最开始的父类)开始继承,直到传递到子类。

    (2)关于super的使用:

    首先super主要用来调用父类的方法,必须放在每一个子类构造函数的第一句,并不是指类中的第一句。

    其次,若是子类函数想调用父类中被覆盖的函数方法,可通过“super.方法名()”调用到父类中的函数;若是子类构造函数,则直接使用“super()”(无参时)或者“super(参数值)”(有参时)调用父类的构造函数。

    (3)编译错误分析:

    在编译时,不断尝试不同的构造方法和调用方法,发现以下错误:

    若父类多了一个有参的构造函数,要么子类构造函数保持一致,super(参数值)调用,要么不写子类构造函数。否则会显示错误。具体如下:

    父类构造函数有参

    使用无参super会错误,即使没有使用super也错误。

     

     

    Super和子类构造函数均加参数才正确

    2.子类与父类的类型转换与使用总结:

    观察以下代码:

    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;//错误!父类m赋值给子类d,需要进行(Dog)m强制类型转换。

                  d=(Dog)m;

                  //d=c;//错误!两个子类不能能相互赋值。

    //            c=(Cat)m;//编译正确,通过强制类型转换,可以将父类变量赋给子类。

     

           }

    }

     总结:

    子类可以给父类直接赋值,比如“m=d;”;但是若父类需要给子类赋值,需要进行类的强制类型转换。可以想象成现实中的亲子关系,父母给孩子是爱的表达,这里面表达了很多;而孩子给父母是天经地义,可以直接给,加强记忆。

    另外两个派生类之间没有关联,不予赋值,就像亲兄妹,没有义务给予经济支持。

    3. 接口多态:使用接口代替抽象基类

    首先区分接口与抽象基类的定义。

    接口:在表面上由几个没有主体代码的方法定义成的集合体,有唯一的名称,可以被继承或其他接口所实现。使用接口主要实现多态性。一个类一次可以实现若干个接口,但一个类只能继承一个父类。需要注意的是,定义在接口中的常量必须被初始化。

    抽象类则是为了使代码复用,可根据实际的编程环境,选择方法。

    4. .分析下方的程序运行结果是什么,并解释会得到这样的输出

     

    假设parent.myvalue=100,child.myvalue=200。

    第一次新建Parent和Child类时,会调用各自的printvalue()函数;分别输出100,200.

    当“Parent=child”时,将child的对象赋给parent,于是再调用“parent.printvalue()”,输出child.myvalue=200;执行“parent.myValue++”,则为parent的myvalue=101。由于子类中重新定义了printValue()方法,覆盖掉了父类中的方法,故即使再调用“Parent.printValue()”依旧输出child.myValue=200。当执行“((child)parent).myValue++”,意思为将parent转化为child,实际调用child.myValue++即201,再次由于父类方法被覆盖,“parent.printValu()”依旧输出child.myValue=201。

    总结:

    当子类与父类拥有一样的方法,并且让一个父类变量引用一个子类对象时,到底调用哪个方法,由对象自己的“真实”类型所决定。这就是说:对象是子类型的,它就调用子类型的方法,是父类型的,它就调用父类型的方法。

    如果子类与父类有相同的字段,则子类中的字段会代替或隐藏父类的字段,子类方法中访问的是子类中的字段(而不是父类中的字段)。如果子类方法确实想访问父类中被隐藏的同名字段,可以用super关键字来访问它。如果子类被当作父类使用,则通过子类访问的字段是父类的!

    实际运用中,尽量避免命名与父类相同的方法。

  • 相关阅读:
    均值回归理论,均值回归法则是指万物最终都将回归于其长期的均值
    文本框仅允许输入大于0的正整数
    Angularjs接收服务端的布尔值
    Ajax POST单个对象或多个对象至API
    ASP.NET MVC程序重构
    查询数据库创建时间
    查询MS SQL的版本号
    获取Data和Log默认路径
    快速查找对象
    表关联使用INNER JOIN实现更新功能
  • 原文地址:https://www.cnblogs.com/somedayLi/p/7805708.html
Copyright © 2011-2022 走看看