一. 接口与抽象类
1.共同点
- 都是上层抽象,为了继承和实现而存在的
- 都不能被实例化(可以使用匿名内部类实例化),但是可以声明一个引用
- 都可以包含抽象方法
2. 接口
2.1 接口名方法默认修饰符
- 方法默认使用 public abstract 修饰
- 接口名默认使用 abstract 修饰
//省略了abstract修饰符
//同:public abstract interface IAnimal
public interface IAnimal {
//省略了public abstract修饰符
//同:public abstract void eat();
void eat();
//默认使用public abstract修饰符
//同:public abstract void sleep();
void sleep();
}
2.2 接口中只能有常量
- 不能定义成员变量(因为类不能初始化),否则会编译报错
- 常量默认使用public修饰,不加修饰符默认也是public
public interface IAnimal {
//省略了public修饰符
//其他类可以通过IAnimal.COUNT_CURRENT调用
final static int COUNT_CURRENT = 1000;
}
2.3 一个接口可以继承多个接口,一个类可以实现多个接口
// 食品接口
public interface IFood { }
// 动物接口
public interface IAnimal { }
// 食物链接口
public interface IAnimalFood extends IAnimal, IFood { }
2.4 普通实现类必须实现类中所有的抽象方法,包括父接口中的方法
抽象类可以不实现接口中的方法
//动物接口
public interface IAnimal {
//吃东西
void eat();
//睡觉
void sleep();
}
//鱼
public class Fish implements IAnimal {
@Override
public void eat() {
System.out.println("fish is eating food");
}
@Override
public void sleep() {
System.out.println("fish is sleeping");
}
}
2.5 java8中新增了default关键字
- 接口可以使用default关键字提供默认实现方法
- 子类可以实现该默认方法,也可以不实现
- 接口中新增方法,子类要全部实现,default关键字解决了接口难以扩展的问题
//动物接口
public interface IAnimal {
// 吃东西
void eat();
// 睡觉,默认实现方法
default void sleep(){
System.out.println("animal is sleeping");
}
}
//鱼
public class Fish implements IAnimal {
@Override
public void eat() {
System.out.println("fish is eating food");
}
//可以重写sleep方法,也可以不重写
@Override
public void sleep() {
System.out.println("fish is sleeping");
}
}
3. 抽象类
3.1 一个类使用了abstract修饰,那么这个类就是抽象类
//抽象宠物类
public abstract class AbstractPet {
//玩耍
protected abstract void play();
}
3.2 抽象类可以实现接口和继承父类,并且不需要实现其中的抽象方法
- 抽象类也可以继承普通类
//抽象宠物类
//没有实现IAnimal接口中的eat()和sleep()方法
public abstract class AbstractPet implements IAnimal {
//宠物名称
private String name;
public AbstractPet(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
}
3.3 如果一个子类没有全部实现父类所有的抽象方法,那么这个子类必须定义为抽象类
- 如果一个子类实现了父类所有的抽象方法,那么子类可以定义为普通类
//抽象宠物类
public abstract class AbstractPet {
//玩耍
protected abstract void play();
}
//抽象宠物狗
//如果不是抽象类,那么编译报错
public abstract class AbstractDog extends AbstractPet { }
3.4 abstract关键字不能和private,static,final关键字一起使用
- 编译报错
- abstract关键字是为了继承而设计的
- 使用了private,static,final修饰的方法不能被重写
二. 继承与实现
java四大特性: 抽象,继承,封装,多态
- 抽象: 对现实事物的建模,也就是类和接口
- 继承: 通过继承类或者实现接口,为有联系的事物建立关联模型
- 封装: 使用修饰符修饰类,成员变量和方法,并对外提供一系列操作食物的方法
- 多态: 继承类,重写或者重载方法,使得不同事物的同一种行为可以产生不同的结果
1.继承
- 继承是类与类,接口与接口之间的关系
- java是单继承,一个类只能继承另一个类
- 一个接口能继承多个接口
- 继承的关键字是extends
1.1 super关键字
- super是一个特殊的关键字,用于指向父类,但是不能赋值给其他变量
- 访问父类的属性,普通方法和构造方法
- 子类的构造函数第一行会默认调用父类的无参构造器(也就是隐式调用super()方法)
- 如果父类没有无参构造器,必须显式调用父类有参构造方法(例如:super(name))
// 抽象宠物类
public abstract class AbstractPet {
//宠物名称
private String name;
//构造函数
public AbstractPet(String name){
//隐式调用Object类的无参构造方法,super();
this.name = name;
}
// 玩耍
protected abstract void play();
// 吃饭
public abstract void eat();
}
//宠物狗
public class Dog extends AbstractPet {
public Dog(String name) {
//因为父类没有提供无参构造器,
//所以显式调用super(name)
super(name);
}
@Override
protected void play() {
System.out.println("dog is playing");
}
@Override
public void eat() {
System.out.println("dog is eating food");
}
}
2.实现
- 实现是类与接口之间的关系
- java是多实现,一个类可以实现多个接口
- 一个接口能继承多个接口
- 实现的关键字是implements
三. 重写与重载
1.重载(Overloading)
- 方法签名不同
- 方法名相同,参数类型或者个数不一样(与返回值无关)
- 为了方便开发和源码阅读,重载方法的一些默认约定
- 为了方便阅读,返回相同的类型
- 为了方便阅读和代码维护,参数按相同的顺序排序
public class Int {
priavte int num;
//默认构造函数
public Int(){}
//重载构造函数
public Int(int num){
this.num = num;
}
//两个数求和
public int sum(int a, int b) {
return a + b;
}
//重载,三个数求和
public int sum(int a, int b, int c) {
return a + b + c;
}
}
2.重写(Overriding):继承过程中, 覆盖父类的方法
- 重写的方法必须与父类方法参数顺序一致
- 重写的方法必须与父类方法返回类型一致
- 重写的方法访问控制修饰符权限必须大于父类方法的访问控制修饰符的权限
- private 方法无法被重写,因为无法被子类访问
- public > protected > default
- 重写的方法不能抛出新的异常,也不能抛出比父类方法更加宽泛的异常
- 为了方便开发和阅读,请使用Override注解进行精确重写
//文件帮助类
public class FileHelper {
// 查找文件
//protected修饰方法,那么实现类的修饰符只能使用public或者protected
//抛出IOException,那么子类只能抛出IOException及其子类,而不能直接抛出Exception异常
protected void find(String path) throws IOException {
System.out.println("FileHelper find file " + path);
}
}
//自定义FileHelper
public class YanggxFileHelper extends FileHelper {
// 查找文件 约定俗称加上Override进行精确重写
// 父类方法使用了protected修饰符,重写方法只能使用public或者protected
//父类方法抛出了IOException,重写方法只能抛出IOException以及子类
@Override
public void find(String path) throws IOException {
System.out.println("FileHelper find file " + path);
}
}
网友评论