Java抽象类与接口

抽象


概念

抽象即没有任何具体的实际内容,在 Java 中抽象的关键字是 abstract
如:

// 抽象类
public abstract class Human{
    // 抽象方法
    public abstract void run();
}public class Worker extends Human{
    public void run(){
        System.out.println("自行车出行");
    }
}
public class Boss extends Human{
    public void run(){
        System.out.println("小汽车出行");
    }
}// 入口测试
Human worker = new Worker();
workder.run(); // 自行车出行
Human boss = new Boss();
boss.run(); // 小汽车出行

使用abstract修饰的类无法被实例化调用,只能实例化子类

抽象方法

有些父类的方法没有具体的实现方式,所以可以定义成abstract方法

public abstract void 方法名();

注意抽象方法不能是private私有方法,不然无法被子类继承,重写

抽象类

包含抽象方法的类必须为抽象类,而抽象类可以不需要有抽象方法,当我们创建一个父类时,需要避免父类被随意实例化,这就要用到abstract
例:

public abstract class A{}
public abstract class B{
    public abstract void b();
}// 不能实例化
A a = new A(); // 编译失败
B b = new B(); // 编译失败

对于子类,可以实现抽象方法,也可以继续保持抽象而不进行具体的实现


public class A1 extends A{}

public abstract class A2 extends A{}
public abstract class B1 extends B{}

public class B2 extends B{
    public void b(){
        System.out.println("子类不是抽象类必须实现父类的抽象方法");
    }
}

应用场景

  1. 对方法进行抽象:当某个方法无法描述或是不方便描述的时候,可以不定义具体的实现并要求由子类去定义,使用 abstract 抽象修饰为未实现方法
  2. 当类不能直接被实例化,或者类不是完整的,应该由子类去扩展并具体实现,那么可以将类修饰为 abstract class 抽象类
  3. 子类继承抽象类以后,子类也会间接获得抽象类中的抽象方法,如果子类不实现抽象方法那么依然必须保持为抽象类,也可以将抽象方法重写从而变为具体类
  4. 将多个子类抽象为一个父类,使用抽象类来实现多态,即抽象类为父类引用

接口


接口定义

接口是一种规范,没有具体实现,符合这些规范的对象都可以看做是接口的实现
比如说一个U盘和一根数据线,他们没有明显的继承关系,但是我们可以把他们都具有的某些特征定义为接口
如:U盘的数据线都具有传输数据功能

public interface USB{
	public void transfer();
}

创建接口

使用interface关键字来创建接口

public class Uimplements USB {
    @Override public void service() {
        System.out.println("通过U盘传送数据");
    }
}
public class 数据线 implements USB {
    public void service() {
        System.out.println("通过数据线传送数据");
    }
}// 这里可以使用【USB接口】作为参数类型
public class 电脑 {
    public void 传送数据(USB usb) {
        usb.service();
    }
}

使用接口

实现接口的类使用 implements 关键字,并且必须实现接口中定义的方法:
类最多只能继承一个父类,但是可以实现多个接口,接口之间用,隔开:

public class B implements 接口1, 接口2{
	...
}

接口与接口之间也具备继承的概念,同样使用extends

public interface B extends A{
	...
}

接口只能继承接口,继承每个接口里面的方法,可以实现多个接口方法整合的作用,所以使得代码的灵活性,扩展性增强

// 定义接口
public interface Program {
    public void programming();
}
public interface busy {
    public void busyness();
}// 符合接口
public class Programmer implements Program, busy {
    public void programming() {
        System.out.println("使用Java编程");
    }
    public void busyness() {
        System.out.println("仔细分析业务");
    }
}

面向接口

面向接口编程也就是面向抽象。面向接口编程指的是程序设计时,面向接口的约定而不考虑具体的实现。

另外,合理地设计 interface 接口和 abstract class 抽象类之间的继承关系,可以充分地复用代码。一般来说,公共逻辑适合放在抽象中,具体逻辑放到各个子类,而接口的层次则代表了抽象的程度。

总结接口的一些特点

  1. 接口定义的方法不能有具体实现(可以使用 default 默认实现),仅仅作为规范和标准
  2. 接口类似抽象类不能实例化,但是可以作为引用类型,实现多态
  3. 接口中的方法默认为 public abstract ,任何实现了接口的类必须重写接口的所有方法
  4. 如果类实现了接口,但是依然没有把所有方法具体实现,那么类必须修饰为抽象类
  5. 一个类可以实现多个接口,这与单继承不一样,同时可以通过接口类型实现多态
  6. 接口之间可以继承,而且可以是多继承,与类的单继承不一样

内部接口

有些类可能依赖一个简单的接口,而这个接口在外部定义意义不大,那么可以把接口直接定义在类中,通过类名.接口名使用该接口:

public class A{
    interface B{
        void f();
    }
    
    public void doSomething(B obj){
        obj.f();
    }
}// 入口测试
A a = new A();
a.doSomething(a.B(){
    @Override 
    public void f(){ /*具体方法内容*/ }
});

接口中也可以定义接口

public interface I1{
    void f1();
    interface I2{
        void f2();
    }
}class MyClass implements I1.I2{
    @Override 
    public void f2() {}
}

接口属性

接口中的属性默认为 public,static,final 即使省略也无法修改,也就是静态常量,所以一般都是使用大写加下划线的方式命名。

interface MyInterface{
    int CONSTANT_A = 100;
    double CONSTANT_B = Math.random();
    public static final String CONSTANT_C = "hello";
}public class MyClass implements MyInterface{}// 入口测试
System.out.println(MyInterface.CONSTANT_A);
System.out.println(MyClass.CONSTANT_C);

接口默认值

接口允许使用默认实现,通过 default 关键字实现:

interface MyInterface{
    default void result() {
        System.out.println();
    }
}class A implements MyInterface{
    @Override 
    public int count(){
    }
}
class B implements MyInterface{
    @Override 
    public void result() {
        System.out.println("重写方法");
    }
}// 入口方法
new A().result();
new B().result();// 重写方法

可以看到,默认方法可以在接口中写方法体,而实现类可以不必重写 default 修饰的默认方法。这样做的好处是:当我们需要给接口新增一个方法时,会涉及到所有实现该接口的类,如果新增的是 default 默认方法,那么实现类就不需要全部修改也可以编译成功,而需要具体实现的仍然可以按需重写新增方法即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

轩尼诗道-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值