目录
1.什么是抽象类?
举一个例子
Shape就是一个抽象类
抽象类中的方法不能被具体实现,并且抽象类不能被实例化。
所以抽象类的存在有什么用呢?
抽象类存在的最大作用,就是被子类继承,实现多态,而由于抽象类中的方法必须被重写,这样就多了一次编译检测,让代码更安全。
这充分利用编译器的校验,在实际开发中非常有用。
package demo2;
/**
* Created with IntelliJ IDEA
* Description:
* User:34398
* Date:2024-03-19
* Time:9:57
*/
abstract class Shape {
abstract void draw();//默认被public abstract修饰
}
//下面的子类如果没有重写父类(抽象类的方法,draw,编译器会报错,如果父类不是抽象类,那么就不会报错)
class Cyc extends Shape {
public void draw() {//重写抽象类中的方法时,一定要写访问权限
System.out.println("画一个圆圈");
}
}
class Rect extends Shape {
public void draw() {//重写抽象类中的方法时,一定要写访问权限
System.out.println("画一个矩形");
}
}
class Flower extends Shape {
public void draw() {//重写抽象类中的方法时,一定要写访问权限
System.out.println("画一个朵花");
}
}
public class staticss {
public static void drawMap(Shape[] shape) {
for (Shape x : shape) {//左边是数组元素的形式参数,右边是数组名
x.draw();
}
}
public static void main(String[] args) {
Cyc cyc=new Cyc();
Flower flower=new Flower();
Rect rect=new Rect();
Shape[] shape={cyc,flower,rect};
drawMap(shape);
}
}
执行结果:
画一个圆圈
画一个朵花
画一个矩形
抽象类的一些特性:
1.不能直接实例化对象
2.抽象方法不能被final修饰
abstract class Shape {
abstract private void draw();
}
// 编译出错
Error:(4, 27) java: 非法的修饰符组合: abstract和private
3.抽象方法不能被被final和static修饰,因为抽象方法要被子类重写
4.抽象类必须被继承,并且继承后子类要重写父类中的抽象方法,否则子类也是抽象类,必须要使用abstract修饰
5.抽象类中不一定包含抽象方法,但是有抽象方法的类一定是抽象类
6.抽象类中可以有构造方法,供子类创建对象时,初始化父类的成员变量
2.什么是接口?
创建一个接口要用一个关键字interface(接口的英文单词)
下面就是一个接口
提示:
1. 创建接口时, 接口的命名一般以大写字母 I 开头.
2. 接口的命名一般使用 "形容词" 词性的单词.
3. 阿里编码规范中约定, 接口中的方法和属性不要加任何修饰符号,让代码整洁
4.接口中的方法必须带类中实现
5.接口中的变量,默认被public static final修饰,因此不能更改
接口的使用(implements关键字):
public class 类名称 implements 接口名称{
// ...
}
接口的特性:
1.接口类型是一种引用类型,但是不能直接new接口的对象
public class TestUSB {
public static void main(String[] args) {
USB usb = new USB();
}
}
// Error:(10, 19) java: day20210915.USB是抽象的; 无法实例化
2.接口中每一个方法都是public的抽象方法, 即接口中的方法会被隐式的指定为 public abstract(只能是 public abstract,其他修饰符都会报错)
public interface USB {
// Error:(4, 18) java: 此处不允许使用修饰符private
private void openDevice();
void closeDevice();
}
3. 接口中的方法是不能在接口中实现的,只能由实现接口的类来实现
4. 重写接口中方法时,不能使用默认的访问权限(因为接口中的方法都是public修饰的)
5. 接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量
6. 接口中不能有静态代码块和构造方法
7. 接口虽然不是类,但是接口编译完成后字节码文件的后缀格式也是.class
8. 如果类没有实现接口中的所有的抽象方法,则类必须设置为抽象类
9. jdk8中:接口中还可以包含default方法
10.一个类可以实现多个接口
11.接口与接口之间可以多继承,但接口不能继承抽象类
interface IRunning {
void run();
}
interface ISwimming {
void swim();
}
// 两栖的动物, 既能跑, 也能游
interface IAmphibious extends IRunning, ISwimming {
}
class Frog implements IAmphibious {
...
}
3.抽象类与接口的对比:
1.可包含的成员
抽象类:
抽象方法---包含
成员变量--也可以包含,子类可以直接继承
成员方法--也可以包含,子类可以直接继承,提高子类的功能
常量-----也可以包含,子类可以直接继承
静态方法--也可以拥有,子类可以直接继承,抽象类的类名也可以直接调用
构造方法———可以包含,因为抽象类中可能包含成员变量,成员变量需要初始化和二次赋值。
接口:
被public static final修饰的成员变量(必须赋值,之后不可更改)
被public abstract修饰的抽象方法
2.继承
抽象类和接口都必须被继承,且子类必须重写所有的抽象方法才能被实例化。
抽象类:不能多继承
接口:一个类可以,实现多个接口
class Animal {
protected String name;
public Animal(String name) {
this.name = name;
}
}
interface IFlying {
void fly();
}
interface IRunning {
void run();
}
interface ISwimming {
void swim();
}
class Frog extends Animal implements IRunning, ISwimming {
public Frog(String name) {
super(name);
}
@Override
public void run() {
System.out.println(this.name + "正在往前跳");
}
@Override
public void swim() {
System.out.println(this.name + "正在蹬腿游泳");