目录
一、抽象类
1.什么是抽象类
2.抽象类的注意事项
3.抽象类与普通类的对比
二、接口
1.接口的简单使用
2.接口的特性
3.接口的使用案例
4.接口和抽象类的异同
一、抽象类
所谓抽象类,就是更加抽象的类,也就是说,这个类不能具体描述某一个对象。
1.什么是抽象类
1.1.引入
下面这是一个子类继承父类,并且重写父类中的eat方法。
class Animal {
public String name;
public Animal(String name) {
this.name = name;
}
public void eat() {
System.out.println("正在吃……");
}
}
class dog extends Animal {
public dog(String name) {
super(name);
}
@Override
public void eat() {
System.out.println(this.name+"正在吃奥里给!");
}
}
public class Test {
public static void main(String[] args) {
Animal animal = new dog("旺财");
animal.eat();
}
}
运行结果:
我们可以发现,父类的eat方法似乎没有什么作用,也不能具体表现某一个具体动物。那我们可不可以不实现父类的eat方法呢?答案当然是可以的。
1.2.抽象方法与类引入
我们在上面的代码进行改进
上述操作完成一个抽象类和抽象方法的撰写。
1.3.抽象类的语法
一个方法没有实现,就需要用abstract修饰;如果一个类包含了抽象方法,那么这个类也必须用abstract修饰。
(1)抽象方法
在修饰符后面,方法返回值前面加上abstract关键字,也可以不加修饰符
(2)抽象类
在class后面加上abstract关键字
2.抽象类的注意事项
抽象类和普通的类没有什么区别。但是可以比普通类多了抽象方法(可以不实现),也比普通类多了abstract关键字。
abstract class Animal {
public String name;
public Animal(String name) {
this.name = name;
}
public abstract void eat();
}
class dog extends Animal {
public dog(String name) {
super(name);
}
@Override
public void eat() {
System.out.println(this.name+"正在吃奥里给!");
}
}
public class Test {
public static void main(String[] args) {
}
}
继续使用上面的代码进行验证。
2.1.抽象类不能实例化
(1)实例化就会报错
(2)原因
因为抽象类不能具体表现一个对象,也就无法实例化
(3)用法
所以,抽象类的出现一般都要配合子类一起出现,借助子类来实例化对象。说明:抽象类一般都是发生在继承的继承上,同样可以发生向上转转型。
2.2.子类继承抽象类的注意点
(1)一个普通类,继承了这个抽象类,那么这个普通类就必须重写抽象类中的抽象方法。
(2)当抽象类中有构造方法,子类也需要调用构造方法来帮助父类进行初始化。
2.3.关于抽象类的语法
(1)抽象方法必须被重写,因此不能被private或final或static修饰
(2)抽象类中,可以有普通的成员变量和成员方法。
(3)A、B都是抽象类,B继承了A。此时有一个普通类C继承了B,C类要重写A、B中的所有抽象方法。(C->B->A)
2.4.抽象类的作用
(1)抽象类的出现,相当于给编译器加上了一层校验。
(2)原因:当子类继承父类时,编译器都会提醒编译器需要重新抽象方法(为后面的多态打下基础)
3.抽象类与普通类的对比
类/异同 | 普通类 | 抽象类 |
---|---|---|
构造方法 | 有 | 有 |
普通成员变量 | 有 | 有 |
普通成员方法 | 有 | 有 |
抽象方法 | 无 | 有 |
实例化 | 允许 | 不允许 |
二、接口
接口就是抽象类的进一步抽象。接口也是一组公共的规范,如果需要使用接口,就需要蹲守接口的一系列规范
1.接口的简单使用
1.1.生活接口举例
如:电脑的USB口,只要符合该接口的规范,就可以插入;又如:电源插座插孔,符号其规范就可以插入,像电脑、电视机、电饭煲等等符合规范的设备
1.2.接口的语法
(1)和定义类进行类比,定义接口只需要把class关键字替换成 interface 即可
(2)定义接口位置
这种定义方式只需要输入接口名字就可以生成接口;如果不选择也可以,但是要自己定义interface+接口名字的形式去定义。
以上就定义好了两个接口,接口中的成员方法和成员变量下面接着讲解。
1.3.接口的成员变量与方法
(1)成员变量
以上原因是什么呢?我们使用idea的功能:Alt+Ins可以生成解决方案
原来是要先赋值,那原因是什么呢?变量初始化时必须赋值的指明该变量被final修饰,不能被修改。
接口中的成员变量特点:
默认被public static final修饰
去掉后
所以,成员变量初始化必须要赋值。定义格式:类型+变量名 = 值
(2)成员方法
显示报错,提示说抽象方法不能被实现
这样就不会再报错,并且没有具体实现的方法,不应该加上abstract修饰吗?看上面,pubblic字体暗了,说明接口的方法默认都是:public abstract修饰的
那接口的成员方法一定不能被实现吗?那倒未必。
1)被static修饰的方法可以被实现
2)被default修饰的成员方法可以实现
default一般是默认的修饰符,也就是不写的时候,但是这里是必须要显示的写出default
1.4.接口的实现
(1)接口不能实例化
接口和抽象类都是不能直接实例化的,所以需要借助子类来完成实例化
(2)子类继承接口
继承接口要使用implements关键字,而不是extends
上面显示报错,因为继承父类的抽象方法需要子类重写
子类实例化
但是一般都不会这样使用接口
以上粗略介绍了接口的一些定义、定义内容、和实现的写法,下面先介绍接口的特性,也就是接口的特点。
2.接口的特性
2.1.关于接口的定义
(1)接口定义的时候要使用 interface 关键字来定义
(2)接口中的成员变量,默认都是 public static final 修饰的;所以定义成员变量的格式为:类型+变量名字 = 初始值;
(3)接口中的成员方法没有实现时,都默认是抽象方法;也就是成员方法默认是 public abstract 修饰的,所以定义成员方法的格式:返回值类型 + 方法名字();
(4)成员方法如果要实现,必须被static 或者 default 修饰
(5)接口名字命名推荐:首字母用大写I,后面跟上接口名字,接口名字首字母也大写
2.2.接口的继承和实现
(1)接口是不能被实例化的
(2)当一个类实现接口的时候,需要使用implements关键字,并且实现之后,要重写接口中的抽象方法
(3)一个类可以实现多个接口(解决了Java中不能多继承的缺点)
(4)继承和实现的顺序:继承类要在实现接口的前面。一个类可以继承一个普通类/抽象类 同时还可以实现多个接口
(5)接口当中不能有静态代码块和构造方法
(6)重写接口当中的抽方法时,只能使用默认的访问权限
(7)接口的生成的字节码文件后缀也是.class
3.接口的使用案例
(1)三个接口
(2)一个抽象类
(3)子类1继承实现
子类2:
(4)main方法实现
运行结果:
(5)代码
public abstract class Animal {
public String name;
public Animal(String name) {
this.name = name;
}
public void eat() {
System.out.println(this.name+"正在吃");
}
}
class Dog extends Animal implements IRun,ISwim {
public Dog(String name) {
super(name);
}
@Override
public void eat() {
System.out.println(this.name+"正在吃狗粮");
}
@Override
public void run() {
System.out.println(this.name+"正在用四条腿跑……");
}
@Override
public void swim() {
System.out.println(this.name+"正在用四条腿游泳……");
}
}
class Duck extends Animal implements IRun,ISwim,IFly {
public Duck(String name) {
super(name);
}
@Override
public void eat() {
System.out.println(this.name+"正在吃鸭粮");
}
@Override
public void run() {
System.out.println(this.name+"正在用两个脚跑……");
}
@Override
public void swim() {
System.out.println(this.name+"正在用两条腿游泳……");
}
@Override
public void fly() {
System.out.println(this.name+"正在用两个翅膀飞……");
}
}
public interface IRun {
void run();
}
public interface IFly {
void fly();
}
public interface ISwim {
void swim();
}
public class Test {
public static void eat(Animal animal) {
animal.eat();
}
public static void fly(IFly fly) {
fly.fly();
}
public static void main(String[] args) {
Dog dog = new Dog("旺财");
Duck duck = new Duck("唐老鸭");
eat(dog);
eat(duck);
fly(duck);
}
}
4.接口和抽象类的异同
4.1.相同点
(1)都有抽象方法
(2)都不能实例化对象
4.2.不同点
(1)抽象类中可以包含普通方法和普通字段,这些普通方法和普通字段在子类中可以直接使用,不必重写;但是接口中不能包含普通方法,子类必须重写所有的抽象方法
(2)一个普通类只能继承一个抽象类,但是可以实现多个接口
以上就是抽象类和接口的全部内容了。