继承
下面有个例子:
类是规则,用来制造对象的规则。我们不断地定义类,用定义的类制造一些对象。类定义了对象的属性和行为,就像图纸决定了房子要盖成什么样子。
一张图纸可以盖很多房子,它们都是相同的房子,但是坐落在不同的地方,会有不同的人住在里面。假如现在我们想盖一座新房子,和以前盖的房子很相似,但是稍微有点不同。任何一个建筑师都会拿以前盖的房子的图纸来,稍加修改,成为一张新图纸,然后盖这座新房子。在面向对象的世界里我们就可以说,新的图纸是由原来的图纸继承得到的;
问题引入
现在需要制作一个媒体资料库;
可以向资料库存放图片、视频;
资料库可以对其包含的所有的图片/视频进行遍历,展示其信息;
图片:title;size;format;px;isCopy
视频:title;size;format;playingTime;isCopy
Java继承的一些机制
-
子类调用方法时优先调用自己的,如果自己没有在调用父类的;
-
子类构造对象时,需要用到super();方法向父类传递对应的参数,并且符合一下顺序:父类构造->子类的定义初始化->构造器初始化
-
如果不调用super,构造器会自动在父类中寻找不带任何参数的构造器
-
要在子类的方法中调用父类的方法,需要用到super关键字
public class Database {
ArrayList<Item> items=new ArrayList<Item>();
public void add(Item item){
items.add(item);
}
public void list(){
for(Item i:items){
i.show();
}
}
}
public class Item {
private String title;
private int size;
private String format;
public Item() {
}
public Item(String title, int size, String format) {
this.title = title;
this.size = size;
this.format = format;
}
public void show(){
System.out.println(title+"."+format);
}
}
public class Photo extends Item {
private int px;
private boolean isCopy=true;
public Photo(String title, int size, String format, int px) {
super(title,size,format);
this.px = px;
}
@Override
public void show(){
System.out.print("photo:");
super.show();
}
}
public class Video extends Item{
private int playingTime;
private boolean isCopy=true;
public Video(String title,int size, String format, int playingTime) {
super(title,size,format);
this.playingTime = playingTime;
}
@Override
public void show(){
System.out.print("video:");
super.show();
}
}
多态
一个变量可以管理自己或子类的对象的现象叫多态
- 子类的对象可以被当作父类的对象来使用
- 赋值给父类的变量
- 传递给需要父类对象的函数
- 放进存放父类对象的容器里
- Java的所有对象变量都是多态的,它能保存不止一种类型的对象
- 它们可以保存的是声明类型的对象(静态类型),也可以是声明类型的子类的对象(动态类型)
- 当我们把一个子类的对象交给父类的变量管理时就发生了向上造型;
造型Cast
-
把一个类的实例对象赋值给另外一个类的变量的过程叫做造型
-
父类的变量可以管理子类的对象(向上造型)
-
子类的变量不能管理父类的对象
Vehicle v=new Vehicle(); Car c=new Car(); v=c; //可以 c=v; //编译错误!会爆红
除非用向下造型,c=(Car)v; 但是前提是v管理的的确是一个Car的对象
-
-
向上造型总是安全的,是默认的,不需要加括号
-
向下造型是强制的,是不安全的,可能会发生异常
-
造型不是类型转换
抽象
现在需要做三个类
矩形,三角形,圆形
每个类里面都需要有计算周长的方法getPerimeter();
和计算面积的方法getArea();
抽象类和抽象方法(abstract)
- 抽象方法——表达概念而无法实现具体代码的方法
- 抽象类——表达概念而无法构造出实体的类
- 有抽象方法的类一定是抽象类,但是抽象类不一定只有抽象方法
- 继承自抽象类的子类一定要重写父类中的抽象方法
两种抽象
- 与具体相对
- 表达概念而非实体
- 与细节相对
- 关注大局而不过分在意具体实现
接口
现在有一个手机类Phone,和人类Person
两者都有发出声音的方法Sound();
我们想把这个公共的方法提取出来但是又不违和;
public interface Soundable{
public void sound();
}
public class Phone implements Soundable{
@Override
public void sound(){
System.out.println("叮铃铃");
}
}
public class Person implements Soundable {
@Override
public void sound(){
System.out.println("你好");
}
}
接口的一些机制
- 接口里的所有方法都是抽象方法,即使前面没有加abstract声明,系统会自动默认
- 接口里的所有变量都是静态变量
- 接口可以继承接口,但不能继承类
- 接口不能有实体
- 一个类可以实现多个接口,实现 用关键字 implements
接口存在的意义
- 将某个功能抽象出来,提高可扩展性
- 是Java成功的关键之一,因为极适合多人写一个大程序
- 也是Java被批评的要点之一,因为容易造成代码膨胀
总结
- 继承类(不管是实体类还是抽象类)侧重于规则和概念
- 实现接口侧重于功能(很多able结尾的接口,如Cloneable,Readable,Runable)