package com.kevin;
class Dog extends Animal{
    private String name;
    public Dog(String name){
        //子类的构造方法必须调用父类的构造方法,如果未手动调用,则默认调用super();故父类一定要存在默认的构造方法,并且该行必须在第一行调用
        //super("父类名字");
        this.name = name;
    }
}
class Animal{
    private String name;
    public String getName(){
        return this.name;
    }
    public Animal(String name){
        this.name = name;
    }
    public Animal(){}
}
public class Test{
    public static void main(String []args){
        Animal animal = new Animal("动物");
        System.err.println(animal.getName());//动物
        animal = new Dog("小旺财");
        System.err.println(animal.getName());//null
        Dog dog = new Dog("旺财");
        System.err.println(dog.getName());//null
    }
}

上述证明:

  • 父类的方法即属性皆属于父类,并不为子类所有,只是可通过子类调用父类的非private方法
  • 通过子类调用父类的方法,操作的为父类的属性
  • 若父子类均存在private 属性A,新建A的实例,调用父类的getA方法,取到的为父类的A,因此为null
package com.kevin;
class Dog extends Animal{
    private String name;
    public Dog(String name){
        this.name = name;
    }
    public String getName(){
        return name;
    }
}
class Animal{
    private String name;
    public String getName(){
        return this.name;
    }

    public Animal(){}

    public Animal(String name){
        this.name = name;
    }
}

public class Test{
    public static void main(String []args){
        Animal animal = new Animal("动物");
        System.err.println(animal.getName());//动物
        Animal animal2 = new Dog("小旺财");
        System.err.println(animal.getName());//小旺财
        Dog dog = new Dog("旺财");
        System.err.println(dog.getName());//旺财

        Test test = new Test();
        test.test(animal);//animal
        test.test(animal2);//animal
        test.test(dog);//dog
    }

    public void test(Animal animal){
        System.out.println("animal");
    }
    public void test(Dog dog){
        System.out.println("dog");
    }
}

上述说明:

  • 父子存在同一方法时,调用方法取决于具体的实例而不是声明的类
  • 多态调用的方法,取决于声明的类而非实例