1.继承
我们把用来做基础派生其它类的那个类叫做父类、超类或者基类,而派生出来的新类叫做子类。Java用关键字extends表示这种继承/派生关系:
class ThisClass extends SuperClass {
//…
}
继承表达了一种is-a关系,就是说,子类的对象可以被看作是父类的对象。Java的继承只允许单继承,即一个类只能有一个父类。
对理解继承来说,最重要的事情是,知道哪些东西被继承了,或者说,子类从父类那里得到了什么。答案是:所有的东西,所有的父类的成员,包括变量和方法,都成为了子类的成员,除了构造方法。构造方法是父类所独有的,因为它们的名字就是类的名字,所以父类的构造方法在子类中不存在。除此之外,子类继承得到了父类所有的成员。
但是得到不等于可以随便使用。每个成员有不同的访问属性,子类继承得到了父类所有的成员,但是不同的访问属性使得子类在使用这些成员时有所不同:有些父类的成员直接成为子类的对外的界面,有些则被深深地隐藏起来,即使子类自己也不能直接访问。下表列出了不同访问属性的父类成员在子类中的访问属性:
public的成员直接成为子类的public的成员,protected的成员也直接成为子类的protected的成员。Java的protected的意思是包内和子类可访问,所以它比缺省的访问属性要宽一些。而对于父类的缺省的未定义访问属性的成员来说,他们是在父类所在的包内可见,如果子类不属于父类的包,那么在子类里面,这些缺省属性的成员和private的成员是一样的:不可见。父类的private的成员在子类里仍然是存在的,只是子类中不能直接访问。我们不可以在子类中重新定义继承得到的成员的访问属性。如果我们试图重新定义一个在父类中已经存在的成员变量,那么我们是在定义一个与父类的成员变量完全无关的变量,在子类中我们可以访问这个定义在子类中的变量,在父类的方法中访问父类的那个。尽管它们同名但是互不影响。
在构造一个子类的对象时,父类的构造方法也是会被调用的,而且父类的构造方法在子类的构造方法之前被调用。在程序运行过程中,子类对象的一部分空间存放的是父类对象。因为子类从父类得到继承,在子类对象初始化过程中可能会使用到父类的成员。所以父类的空间正是要先被初始化的,然后子类的空间才得到初始化。在这个过程中,如果父类的构造方法需要参数,如何传递参数就很重要了。
如果子类中有和父类一样的成员变量,那么父类中的成员变量就会隐藏。
package lianxi;
public class Item {
private String name;
private int playingtime;
private boolean gotit=true;
public Item(String name, int playingtime) {
super();
this.name = name;
this.playingtime = playingtime;
}
public void print() {
System.out.print(name);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
package lianxi;
public class DVD extends Item {
// private String name;
private String editor;
// private int playingtime;
// private boolean gotit=true;
public DVD(String name, String editor, int playingtime) {
super(name,playingtime);
// this.name = name;
this.editor = editor;
// this.playingtime = playingtime;
}
public void print() {
System.out.print("DVD:");
super.print();
System.out.println(":"+editor);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
package lianxi;
public class CD extends Item{
// private String name;
private String artist;
// private int playingtime;
// private boolean gotit=true;
public CD(String name, String artist, int playingtime) {
super(name,playingtime);
// this.name = name;
this.artist = artist;
// this.playingtime = playingtime;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
}
public void print() {
System.out.print("CD:");
super.print();
System.out.println(":"+artist);
}
}
package lianxi;
import java.util.ArrayList;
public class Database {
// ArrayList<CD> cdlist=new ArrayList<CD>();
// ArrayList<DVD> dvdlist=new ArrayList<DVD>();
ArrayList<Item> itemlist=new ArrayList<Item>();
public void add(CD cd) {
itemlist.add(cd);
}
public void add(DVD dvd) {
itemlist.add(dvd);
}
public void list() {
for(Item c:itemlist) {
c.print();
}
// for(DVD d:itemlist) {
// d.print();
// }
}
public static void main(String[] args) {
Database db=new Database();
CD cd=new CD("abc","abc",60);
db.add(cd);
db.add(new CD("def","def",60));
db.add(new DVD("ggg","xxx",120));
db.list();
}
}