在TestInhers.java 中子类在显示的调用父类的另一个构造函数时,这句代码必须放在第一句。
构造函数,是一种特殊的方法。主要用来在创建对象时初始化对象,即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中。特别的一个类可以有多个构造函数,可根据其参数个数的不同或参数类型的不同来区分它们即构造函数的重载。
构造函数是初始化已创建好的对象中成员变量的,而不是创建对象的,构造函数只是进一步为已创建的对象属性赋值对,使之更新“想象”中的对象,对象在非静态代码块执行之前,在构造方法调用之前已经存在了。子类拥有父的成员变量和成员方法,如果不调用,则从父类继承而来的成员变量和成员方法得不到正确的初始化。不能反过来调用也是这个原因,因为父类根本不知道子类有什么变量而且这样一来子类也得不到初始化的父类变量,导致程序运行出错!
构造函数的特点:无论是用户自定义的构造函数还是默认构造函数都主要有以下特点:
①. 在对象被创建时自动执行;
②. 构造函数的函数名与类名相同;
③. 没有返回值类型、也没有返回值;
④. 构造函数不能被显式调用。
在fruit.java中,fruit类覆盖了object类中的tostring方法
在“+”运算中,当任何一个对象与一个String对象,连接时,会隐式地调用其toString()方法,默认情况下,此方法返回“类名 @ + hashCode”。为了返回有意义的信息,子类可以重写toString()方法。
1 package class4; 2 3 class Mammal{} 4 class Dog extends Mammal {} 5 class Cat extends Mammal{} 6 7 public class TestCast 8 { 9 public static void main(String args[]) 10 { 11 Mammal m; 12 Dog d=new Dog(); 13 Cat c=new Cat(); 14 m=d; //子类可以赋值给父类 15 //d=m; 16 d=(Dog)m; //当父类赋值给子类是必须用强制的类型转换 17 //d=c; 18 c=(Cat)m; 19 20 } 21 }
在TestCast.java中当将父类的对象赋值给子类对象时会出错,父类赋值给子类必须进行强制类型转换
1 package class4; 2 3 class Parent 4 5 { 6 7 public int value=100; 8 9 public void Introduce() 10 { 11 12 System.out.println("I'm father"); 13 14 } 15 16 17 18 19 } 20 21 class Son extends Parent 22 { 23 24 public int value=101; 25 26 public void Introduce() 27 { 28 29 System.out.println("I'm son"); 30 31 } 32 33 } 34 35 36 class Daughter extends Parent 37 { 38 39 public int value=102; 40 public void Introduce() 41 { 42 43 System.out.println("I'm daughter"); 44 45 } 46 47 } 48 49 public class TestPolymorphism 50 { 51 52 53 public static void main(String args[]) 54 { 55 56 Parent p=new Parent(); 57 58 p.Introduce(); 59 60 System.out.println(p.value); 61 62 p=new Son(); 63 64 p.Introduce(); 65 66 System.out.println(p.value); 67 68 p=new Daughter(); 69 70 p.Introduce(); 71 72 System.out.println(p.value); 73 74 75 } 76 77 78 }
此程序的运行结果为:
Parent.printValue()100
child.printValue()200
child.printValue()200
child.printValue()200
child.printValue()201
原因:(1)当子类与父类拥有一样的方法,并且让一个父类变量引用一个子类对象时,到底调用哪个方法,由对象自己的“真实”类型所决定,这就是说:对象是子类型的,它就调用子类型的方法,是父类型的,它就调用父类型的方法。
(2)如果子类与父类有相同的字段,则子类中的字段会代替或隐藏父类的字段,子类方法中访问的是子类中的字段(而不是父类中的字段)。如果子类方法确实想访问父类中被隐藏的同名字段,可以用super关键字来访问它。
(3)如果子类被当作父类使用,则通过子类访问的字段是父类的!