Java 继承和多态
一、
1、媒体资料库
package dome; //CD类 public class CD { private String title;//名称 private String artist;//歌手 private int numofTracks;//几首歌 private int playingTime;//播放时间 private boolean gotIt;//是否借出 private String comment;//评论 //构造函数初始化对象 public CD(String title, String artist, int numofTracks, int playingTime, String comment) { super(); this.title = title; this.artist = artist; this.numofTracks = numofTracks; this.playingTime = playingTime; this.comment = comment; } public void print() //类输出 { System.out.println("CD:"+title+"-"+artist); } public static void main(String[] args) { // TODO Auto-generated method stub } }
package dome; //DVD类 public class DVD { private String title; private String director; private int playingTime; private boolean gotIt; private String comment; public DVD(String title, String director, String comment, int playingTime) { super(); this.title = title; this.director = director; this.playingTime = playingTime; this.comment = comment; } public void print() { System.out.println("DVD:"+title+"-"+director); } }
package dome; import java.util.ArrayList; //媒体库 public class Datebase { private ArrayList<CD> listCD=new ArrayList<CD>(); private ArrayList<DVD> listDVD=new ArrayList<DVD>(); public void add(CD cd) { listCD.add(cd); } public void add(DVD dvd) { listDVD.add(dvd); } public void list() { for(CD cd:listCD) { cd.print(); } for(DVD dvd:listDVD) { dvd.print(); } } public static void main(String[] args) { Datebase db=new Datebase(); db.add(new CD("abc", "abc", 4, 60, "***")); db.add(new CD("def", "def", 4, 60, "***")); db.add(new DVD("xxx","aaa","...", 60)); db.add(new DVD("yyy","bbb","...", 60)); db.list(); } }
2、上面程序有很多重复的代码,利用父类和子类的继承,可以将公共的提取出来,作为父类,独有的作为子类,然后利用protected 或者super,实现相互调用
父类 item类程序
package dome; public class item { protected String title;//将private 改为protected ,这样整个包下,所有子类都可以访问 private int playingTime;//播放时间 private boolean gotIt;//是否借出 private String comment;//评论 //构造器赋初始值 public item(int playingTime, String comment) { super(); this.playingTime = playingTime; this.comment = comment; } public void print() { System.out.print(playingTime+"-"+comment);//这两个private在子类输出不了,在父类定义输出 } public static void main(String[] args) { // TODO Auto-generated method stub } }
由于两者作用范围不一样,所以具体的代码也不一样。
private 需要在父类中就定义构造器,并初始化。利用super传值。
protected则不用再父类中做操作,但是这种方法相对不安全。
子类
package dome;
//CD类
public class CD extends item{//继承item
private String artist;//歌手
private int numofTracks;//几首歌
//构造函数初始化对象
public CD(String title, String artist, int numofTracks, int playingTime, String comment) {
super(playingTime, comment);
this.title = title;
this.artist=artist;
this.numofTracks = numofTracks;
}
public void print() //类输出
{
System.out.print("CD:"+title+"-"+artist+numofTracks+"-");//直接输出
super.print();//调用父类输出
System.out.println("\n");
}
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
package dome;
public class DVD extends item {//继承 item
private String director;//导演
public DVD(String title, String director, String comment, int playingTime) {
super(playingTime,comment);
this.title = title;
this.director = director;
}
public void print() {
System.out.print("DVD:"+title+"-"+director+"-");//只有title,director 可以输出
super.print();//调用父类的print
System.out.println("\n");
}
}
主程序
package dome;
import java.util.ArrayList;
public class Datebase {
private ArrayList<item> listItem=new ArrayList<item>();//用父类
public void add(item i)
{
listItem.add(i);
}
public void list()
{
for(item i:listItem)
{
i.print();
}
}
public static void main(String[] args) {
Datebase db=new Datebase();
db.add(new CD("abc", "abc", 4, 60, "***"));//本来db add的是item,这里用子类对象来赋值给父类变量,向上造型
db.add(new CD("def", "def", 4, 60, "***"));
db.add(new DVD("xxx","aaa","...", 60));
db.add(new DVD("yyy","bbb","...", 60));
db.list();
}
}
再有注意,print()构造函数由于子类输出的独特性,所以在子类总构造了输出函数,
父类和子类中都有print输出函数,运行时会根据变量类型(item,CD,DVD )来选择适当的函数。这叫多态。
二、
2.1
其实就是定义了一个父类将所有共有的可以提取出来,然后子类当父类,进行运行,简化重复代码。
package Hello; import java.util.ArrayList; import java.util.HashSet; public class test { public static void main(String[] args) { String s = "hello"; s="hi"; System.out.println(s); } }
可以看到s的对象是“Hello”时,id=19;
对象是hi时,id=23;可以看出并不是Hi将hello替换掉了,而是s指向了新的对象。
2.2
注意变量和对象的区别。变量只是声明了个名称,对象则是new了初始化个值,
父类的对象不可以赋值给子类的变量
子类的对象可以赋给父类的变量。
debug 程序如下
22行运行后,得到如下结果
23行运行完后
24行运行完后
it和cd指向了同一个对象。
对于基本数据类型叫类型转换,对对象来说叫造型。
三、多态
根据变量类型,自动调用合适的函数。
四、
object的函数
4.1 toString()
利用Object的toString()函数输出
修改item
package dome;
public class item {
protected String title;//将private 改为protected ,这样整个包下,所有子类都可以访问
private int playingTime;//播放时间
private boolean gotIt;//是否借出
private String comment;//评论
//构造器赋初始值
public item(int playingTime, String comment) {
super();
this.playingTime = playingTime;
this.comment = comment;
}
public void print() {
System.out.print(playingTime+"-"+comment);//这两个private在子类输出不了,在父类定义输出
}
@Override
public String toString() {
// return "item [title=" + title + ", playingTime=" + playingTime + ", gotIt=" + gotIt + ", comment=" + comment
// + ", toString()=" + super.toString() + "]";
return playingTime+"-"+comment;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
修改CD
package dome;
//CD类
public class CD extends item{//继承item
private String artist;//歌手
private int numofTracks;//几首歌
//构造函数初始化对象
public CD(String title, String artist, int numofTracks, int playingTime, String comment) {
super(playingTime, comment);
this.title = title;
this.artist=artist;
this.numofTracks = numofTracks;
}
public void print() //类输出
{
System.out.print("CD:"+title+"-"+artist+"-"+numofTracks+"-");//直接输出
super.print();//调用父类输出
System.out.println("\n");
}
@Override
public String toString() {
//return "CD: [artist=" + artist + ", numofTracks=" + numofTracks + ", toString()=" + super.toString() + "]";
return "CD:"+title+"-"+artist+"-"+numofTracks+"-"+super.toString();
}
public static void main(String[] args) {
// TODO Auto-generated method stub
CD cd=new CD("abc","def",4,60,"good");
cd.print();//调用 print() 函数输出
System.out.println(cd);//调用toString()函数,不过需要自己修改输出格式
}
}
4.2
package dome; public class DVD extends item {//继承 item private String director;//导演 public DVD(String title, String director, String comment, int playingTime) { super(playingTime,comment); this.title = title; this.director = director; } public void print() { System.out.print("DVD:"+title+"-"+director+"-");//只有title,director 可以输出 super.print();//调用父类的print System.out.println("\n"); } public static void main(String[] args) { DVD dvd=new DVD("xxx","aaa","...", 60); DVD dvd1=new DVD("xxx","aaa","...", 60); DVD dvd2; dvd2=dvd; System.out.println(dvd.equals(dvd1));//调用了Object的equals System.out.println(dvd.equals(dvd2)); } }
可以看出dvd和dvd2是一样的,因为dvd2是由dvd赋值过去的,他们共同管理一个位置。
而dvd1是new初始化生成的,位置不同。
但是这里他们的内容明明是相同的,所以还需要修改代码。
4.3
package dome;
public class DVD extends item {//继承 item
private String director;//导演
public DVD(String title, String director, String comment, int playingTime) {
super(playingTime,comment);
this.title = title;
this.director = director;
}
public void print() {
System.out.print("DVD:"+title+"-"+director+"-");//只有title,director 可以输出
super.print();//调用父类的print
System.out.println("\n");
}
@Override
public boolean equals(Object obj) {
// TODO Auto-generated method stub
//return super.equals(obj);
DVD dvd=(DVD)obj;//向下造型
return director.equals(dvd.director);//导演相同
}
public static void main(String[] args) {
DVD dvd=new DVD("xxx","aaa","...", 60);
DVD dvd1=new DVD("xxx","aaa","...", 60);
DVD dvd2;
dvd2=dvd;
System.out.println(dvd.equals(dvd1));//调用了Object的equals
System.out.println(dvd.equals(dvd2));
}
}
@Override 表明下面的函数是覆盖了父类的函数(Object的函数) ,该函数表头是固定的,不可以修改。
五、类的扩展
构造函数
创建print函数
package dome; public class videogame extends item { private int numofplayer; private String gamename; //对象初始化 public videogame(int numofplayer,String gamename,int playingTime, String comment) { super(playingTime, comment); // TODO Auto-generated constructor stub this.numofplayer=numofplayer; this.gamename=gamename; } @Override public void print() { // TODO Auto-generated method stub System.out.print("videogame:"+gamename+"-"+numofplayer+"-");//只有title,director 可以输出 super.print();//调用父类的print System.out.println("\n"); } @Override public String toString() { // TODO Auto-generated method stub return "videogame:"+gamename+"-"+numofplayer+"-"+super.toString(); } public static void main(String[] args) { videogame vg=new videogame(5,"hah",30,"great"); vg.print(); System.out.println(vg); } }