一、类的继承性
1、Student类继承Person类。代码:MyStudentDemo.java
class Student extends Person
{
private String speciality;
}
public class MyStudentDemo
{
public static void main(String[] args)
{
Person p1 = new Person("张三", new MyDate(1998, 3, 7));
p1.count();
MyStudent s1 = new MyStudent();
s1.count();
Person p2 = new Person(p1);
s1.count();
System.out.println("p1:" + p1);
System.out.println("s1:" + s1);
System.out.println("p1:" + p2);
s1.count();
s1.howMany(); //看来Person类的构造函数中都用到了count++的
s1.set("王五", new MyDate(1994, 01, 06));
System.out.println("s1:" + s1 + " " + s1.getName() + "比" + p1.getName() + "大" + s1.oldThan(p1) + "岁");
s1.finalize();
Person.howMany();
}
}
2、问题:子类不能继承父类的构造函数,那为什么子类会自动使用父类的默认构造函数:
- 当一个类没有声明构造方法时,Java为该类提供默认构造方法,调用super()执行父类无参数的构造方法。例如:代码:test.java。new Zi()调用默认构造方法,自动执行父类构造方法Fu()。注:每个类都要声明无参数的构造方法,即使自己不用,也要为子类准备着。
class Fu { String name; Fu() { this("fu lei"); } Fu(String name) { this.name = name; } public String toString() { return this.name; } } class Zi extends Fu { } class test { public static void main(String[] args) { Zi z1 = new Zi(); //子类不能继承父类的构造方法,难道默认构造方法不算吗? //Zi z2 = new Zi("张三"); //子类不能继承父类的构造方法。 System.out.println(z1); //System.out.println(z2); } }
3、子类使用super()调用父类构造方法
- super([参数列表]) //调用父类同参数的构造方法
class Fu
{
String name;
Fu()
{
this("fu lei");
}
Fu(String name)
{
this.name = name;
}
public String toString()
{
return this.name;
}
}
class Zi extends Fu
{
Zi()
{
super("王五"); //子类使用super()调用父类构造方法
}
}
class test
{
public static void main(String[] args)
{
Zi z1 = new Zi();
System.out.println(z1);
}
}
4、继承原则:
- 子类继承父类的成员变量
- 子类继承父类除构造方法以为的成员方法
- 子类不能继承父类的构造方法
5、以下两种情况,Java默认执行super(),调用父类的构造方法
- 当一个类没有声明构造方法时,Java为该类提供默认构造方法,调用super()执行父类无参数的构造方法。
- 如果子类的构造方法没有调用super()或this(),Java将默认执行super()。
- 注:super()调用必须是第一条语句
二、类的多态性
1、问题:覆盖和重载的区别?
2、Student类重定义从父类继承来的某些成员。代码:MyStudentDemo.java
//MyStudentDemo.java
class Student extends Person
{
private String number;
private String speciality;
private static int max = 0; //当前最大编号
//为什么max加了static,max的值才会每次加1呢?
private static int count = 0; //Student类对象计数器,隐藏了父类的count
Student()
{
}
Student(String name, MyDate birthday, String speciality)
{
super(name, birthday); ////调用父类的构造方法
this.max++;
this.number = MyDate.getThisYear() + "0602" + String.format("%04d", max);
//类名.方法()
//String.format("%04d", max) 这个格式怎么来的呀?API没看懂
this.speciality = speciality;
this.count++;
}
Student(Person p, String speciality)
{
this(p.name, new MyDate(p.birthday), speciality);
//深拷贝p:应该就是new MyDate吧,让子类和父类不是同一个引用
}
Student(Student s) //深拷贝构造方法
{
this(s.name, new MyDate(s.birthday), s.speciality);
}
public void set(String name, MyDate birthday, String speciality)
{
super.set(name, birthday);
this.setSpec(speciality);
}
public void setSpec(String speciality)
{
this.speciality = speciality;
}
public String toString()
{
return this.number + "," + super.name + "," + super.birthday + "," + this.speciality + "专业";
//可以直接用父类的成员变量
//super. this.都可以省略
}
public static void howMany()
{
Person.howMany();
System.out.println(count + "个Student对象");
}
public void finalize()
{
super.finalize();
//System.out.println("释放对象(" + this + ")"); //super.finalize();已经有这句话了
this.count--;
}
}
class MyStudentDemo
{
public static void main(String[] args)
{
Person p1 = new Person("张三", new MyDate(1993, 3, 8));
Student s1 = new Student(p1, "计算机");
Student s2 = new Student(s1);
s2.set("李四", new MyDate(1992, 4, 3), "会计");
s2.howMany();
System.out.println("p1:" + p1);
System.out.println("s1:" + s1);
System.out.println("s2:" + s2);
System.out.println(s2.getName() + "比" + s1.getName() + "大" + s2.oldThan(s1) + "岁");
s2.finalize();
Student.howMany();
}
}