以继承方式实现的媒体资料库,在课程代码实现的基础上,请实现一个表达MP3的媒体类型,能和CD、DVD一样存放进这个Database。
Item
public class Item {
protected String title;
protected int playingTime;
protected boolean gotIt = false;
protected String comment;
public Item(){
}
public Item(String title, int playingTime, boolean gotIt, String comment) {
this.title = title;
this.playingTime = playingTime;
this.gotIt = gotIt;
this.comment = comment;
}
public void print() {
System.out.println(title);
}
}
CD
public class CD extends Item {
private String artist;
private int numofTracks;
private int playingTime;
private boolean gotIt = false;
private String comment;
public CD(String title, String artist, int numofTracks, int playingTime, String comment) {
super(title, playingTime, false, comment); //如果有super就按照super的构造器.没有则寻找父类的构造器
// this.title = title;
this.artist = artist;
this.numofTracks = numofTracks;
// this.playingTime = playingTime;
// this.comment = comment;
}
public void print() {
System.out.println(artist);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CD cd = (CD) o;
if (numofTracks != cd.numofTracks) return false;
if (playingTime != cd.playingTime) return false;
if (gotIt != cd.gotIt) return false;
if (!artist.equals(cd.artist)) return false;
return comment != null ? comment.equals(cd.comment) : cd.comment == null;
}
@Override
public int hashCode() {
int result = artist.hashCode();
result = 31 * result + numofTracks;
result = 31 * result + playingTime;
result = 31 * result + (gotIt ? 1 : 0);
result = 31 * result + (comment != null ? comment.hashCode() : 0);
return result;
}
public static void main(String[] args) {
CD cd1 = new CD("a", "a", 2, 60, "good");
CD cd2 = new CD("a", "a", 2, 60, "good");
System.out.println(cd1.equals(cd2)); //判断相等需要override新方法
}
}
结果为:true
DVD
public class DVD extends Item {
private String title;
private String director;
private int playingTime;
private boolean gotIt = false;
private String comment;
public DVD(String title, String director, int playingTime, String comment) {
super(title, playingTime, false, comment);
this.title = title;
this.director = director;
this.playingTime = playingTime;
this.comment = comment;
}
public void print() {
System.out.println("DVD:");
super.print();
System.out.println(director);
}
}
Database
/**
* 父类的东西都继承给了子类,如果父类有private则子类不能碰,但可通过父类的函数去碰
* 在谁的函数里头指的那个成员函数变量就是谁的.如果子类父类出现同名的成员变量.
* 子类父类都各自拥有.
*/
public class Database {
// private ArrayList<CD> listCD = new ArrayList<CD>();
// private ArrayList<DVD> listDVD = new ArrayList<DVD>();
private ArrayList<Item> listItem = new ArrayList<Item>(); //子类的对象可以存放在父类的容器里
public void add(Item item) //多态变量=不止一种类型的对象,它们可保存声明类型的变量,当把子类的对象赋给父类的对象时,就发生了向上造型.
{
listItem.add(item);
}
// public void add(CD cd) {
// listCD.add(cd);
public void list() {
for (Item item : listItem ) {
item.print();
}
}
// for (CD cd : listCD) {
// cd.print();
// }
// }
public static void main(String[] args) {
//不可能让一个对象赋值一个对象
Database db = new Database();
db.add(new CD("abc", "abc", 100, 60, "ok")); //子类的对象可以传递给需要的父类对象的函数
db.add(new CD("ddd", "abc", 100, 60, "ok"));
db.add(new DVD("eee", "qqf", 120, "well"));
db.list();
}
}
变量item可以引用任何item子类类型的对象(CD/DVD),这叫多态,即一种类型的变量,可引用多种实际类型对象。这样,对于变量item,它就有两个类型,类型item,我们称之为item的静态类型,类型CD/DVD,我们称之为item的动态类型。在Database的add方法中,
db.add()
调用的是其对应动态类型的add方法,这称之为方法的动态绑定。子类对象赋值给父类引用变量,这叫向上转型,转型就是转换类型,向上转型就是转换为父类类型。
使用继承一方面可以复用代码,公共的属性和行为可以放到父类中,而子类只需要关注子类特有的就可以了,另一方面,不同子类的对象可以更为方便的被统一处理。
在
new
的过程中,父类的构造方法也会执行,且会优先于子类先执行。super
用于指代父类,可用于调用父类构造方法,访问父类方法和变量。super
的使用与this
有点像,但super
和this
是不同的,this
引用一个对象,是实实在在存在的,可以作为函数参数,可以作为返回值,但super
只是一个关键字,不能作为参数和返回值,它只是用于告诉编译器访问父类的相关变量和方法。