zoukankan      html  css  js  c++  java
  • 多态与继承的二三事

    1.子类父类拥有同名的方法时……

    测试代码:


    public class ParentChildTest {
    public static void main(String[] args) {
    Parent parent=new Parent();
    parent.printValue();
    Child child=new Child();
    child.printValue();

    parent=child;
    parent.printValue();

    parent.myValue++;
    parent.printValue();

    ((Child)parent).myValue++;
    parent.printValue();

    }
    }

    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);
    }
    }

    预测结果:

    100

    200

    200

    101

    201

    测试结果:

    原因分析与总结:

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

    b.这个特性实际上就是面向对象“多态”特性的具体表现。

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

    d.如果子类被当作父类使用,则通过子类访问的字段是父类的!

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

    测试代码:


    class Grandparent
    {


    public Grandparent()
    {

    System.out.println("GrandParent Created.");

    }


    public Grandparent(String string)
    {

    System.out.println("GrandParent Created.String:" + string);

    }

    }

    class Parent extends Grandparent
    {


    public Parent()
    {

    //super("Hello.Grandparent.");

    System.out.println("Parent Created");

    // super("Hello.Grandparent.");

    }

    }

    class Child extends Parent
    {


    public Child()
    {

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

    }

    }

    public class TestInherits
    {


    public static void main(String args[])
    {

    Child c = new Child();

    }

    }

    测试结果:

    显式调用GrandParent的另一个构造函数,注意这句调用代码是否是第一句,影响重大!

    通过 super 调用基类构造方法,必须是子类构造方法中的第一个语句。

    3.

    参看ExplorationJDKSource.java示例 此示例中定义了一个类A,它没有任何成员

    测试代码

    public class E {
    public static void main(String[] args)
    {
    System.out.println(new A());
    }

    }
    class A{}

    测试结果

    原因分析

    前面示例中,main方法实际上调用的是: public void println(Object x),这一方法内部调用了String类的valueOf方法。

    valueOf方法内部又调用Object.toString方法:

    public String toString() { return getClass().getName() +"@" + Integer.toHexString(hashCode()); } hashCode方法是本地方法,由JVM设计者实现: public native int hashCode();

    4.

    神奇的“+”号

    测试代码

    public class Fruit
    {

    public String toString()
    {
    return "Fruit toString.";
    }

    public static void main(String args[])
    {
    Fruit f=new Fruit();
    System.out.println("f="+f);
    // System.out.println("f="+f.toString());
    }
    }

    测试结果

    原因分析与总结

    a.前页的示例中,Fruit类覆盖了Object类的toString方法。

    b.在“+”运算中,当任何一个对象与一个String对象,连接时,会隐式地调用其toString()方法,默认情况下,此方法返回“类名 @ + hashCode”。为了返回有意义的信息,子类可以重写toString()方法。

    5.怎样判断对象是否可以转换?

    测试代码

    public class TestInstanceof
    {
    public static void main(String[] args)
    {
    //声明hello时使用Object类,则hello的编译类型是Object,Object是所有类的父类
    //但hello变量的实际类型是String
    Object hello = "Hello";
    //String是Object类的子类,所以返回true。
    System.out.println("字符串是否是Object类的实例:" + (hello instanceof Object));
    //返回true。
    System.out.println("字符串是否是String类的实例:" + (hello instanceof String));
    //返回false。
    System.out.println("字符串是否是Math类的实例:" + (hello instanceof Math));
    //String实现了Comparable接口,所以返回true。
    System.out.println("字符串是否是Comparable接口的实例:" + (hello instanceof Comparable));
    String a = "Hello";
    //String类既不是Math类,也不是Math类的父类,所以下面代码编译无法通过
    //System.out.println("字符串是否是Math类的实例:" + (a instanceof Math));
    }
    }

    测试结果

  • 相关阅读:
    Docker学习笔记-Redis 安装
    CentOS搭建FTP服务
    Docker学习笔记-Docker for Windows 安装
    Docker学习笔记-Docker for Linux 安装
    (转载)Javascript 中的非空判断 undefined,null, NaN的区别
    MongoDB
    RabbitMQ
    GIT学习笔记——常用命令
    Evanyou Blog 彩带
    Evanyou Blog 彩带
  • 原文地址:https://www.cnblogs.com/woshitiancai/p/7811059.html
Copyright © 2011-2022 走看看