[Java]抽象类和接口

一:抽象类的介绍

二:接口的介绍

三:接口的应用

一:抽象类的介绍

1. 抽象类的概念:

在面对对象的概念中,类是用来描述一个对象的集合,即一个类中包含了这个对象足够的信息。而当一个类中没有足够的信息来描述一个具体的对象时,这样的类就是抽象类。

比如:在进入图书系统中选择功能页面时,不同的用户登录有不同的菜单menu。

 由上图可知:

(1).User是用户类,是各种用户的共性的集合体现,不是具体的某一种类型的用户,所以内部的menu()方法无法有具体的实现。

(2).Student是学生类,是用户类的一种,因此与User是继承关系。而学生类是一种具体的类型,内部的menu()可以实现,如借阅图书等。

(3).Administractor是管理员类,是用户类的一种,因此与User是继承关系。而管理员类是一种具体的类型,内部的menu()可以实现,如增加图书等。

(4).因此,用户类User它不能描述一个具体的事物。它是抽象的,有时可以代表Student,有时可以代表Administractor,所以把这种类叫做抽象类。

2.抽象类的语法:

2.1 抽象类:被关键字abstract修饰的类

public abstract class User {
    //抽象类
}

2.2 抽象方法:被关键字abstract修饰的方法

public abstract class User {
    //抽象方法
    public abstract void menu();
}
//抽象方法是没有具体的实现内容的,若要进行实现内容,则编译器会报错

注:1. 抽象类中可以没有抽象方法,但有抽象方法的类一定是抽象类。

        2. 抽象类也是类,内部可以包含普通方法和成员变量以及构造方法。

3. 抽象类的特性

3.1 不能被实例化,即不能创建一个抽象类的对象。

你若在编译器上实例化一个抽象类,那编译就不会通过。

3.2 抽象方法不能被访问限定修饰符private修饰。

如果有一个普通类继承了抽象类,那这个类必须重写抽象类中的抽象方法,否则编译器会报错。

 而当用privatr修饰了抽象方法,那抽象方法只能在本类中,不能在子类中重写。

此时编译器也会报警告:

3.3 抽象方法不能被关键字final修饰

被final修饰的类和成员方法不能被继承,当类继承抽象类时,同时要继承其中的抽象方法,这里存在矛盾,private不能与abstract共存。

 3.4 抽象方法不能被关键字static修饰

被static修饰的方法是属于类的方法,可以通过类的引用去调用它,但抽象类是不能进行实例化的,所以存在矛盾,static与abstract共存。

注:在这里强调一下抽象类的存在。当一个抽象类被创建时,那它必然是要被某些类继承的,否则就没有存在的必要!而抽象方法一般是这些类中的共同拥有的方法,是必然要在子类中进行重写的。抽象类是多态思想上的一步,单单讨论抽象类的意义会理解的有点抽象。

由此可以引出:
继承了抽象类的类,如果这个类不是抽象类,就必须要重写抽象类中的抽象方法,如果是一个抽象类继承了一个抽象类,就不用重写抽象方法。

1. 普通类继承抽象类:

public abstract class User {
    //抽象方法
    abstract  void menu();

}
//普通类继承抽象类需重写抽象方法
class Code extends User{

    @Override
    void menu() {

    }
}

2. 抽象类继承抽象类:

public abstract class User {
    //抽象方法
    abstract void menu();

}

//抽象类继承抽象类可以不用重写抽象方法
abstract class Test extends User{
    //自己的抽象方法
    abstract void test();
}

3. 若有一个普通类继承了一个抽象类,而这个抽象类也继承了一个抽象类时,则这个普通类要重写所有的抽象方法:

public abstract class User {
    //抽象方法
    abstract void menu();
}
abstract class Test extends User{
    //自己的抽象方法
    abstract void test();
}

class Demo extends Test{
    @Override
    void menu() {
    }
    @Override
    void test() {
    }
}

4. 抽象类的作用:

4.1 减少代码的复用:抽象类是必然要作为父类使用的,而父类中的代码往往是提取了多个类中共同拥有的代码,能减少代码的复用。

4.2 思想的矫正:子类调用方法,那应该是由子类去实现这个方法的,而抽象类不能实例化,也就不能通过父类的引用去实现某个方法,必须要在子类中重写然后再去实现(一种逻辑思想)。而当继承了一个普通类时,此时通过父类去进行操作,编译器不会报错。我觉得这是一种思想的矫正,而不是说继承普通类比继承抽象类的代码更少一些。同时还能利用抽象方法必须要在子类中进行重写的特性来让编译器校验代码有无问题!

二:接口的介绍

1. 接口的概念:

1.1 接口类似于一种功能或者特性,当一个类实现了这个接口,那就代表这个类拥有了这种功能或特性。  (即接口当中的抽象方法)

1.2 在java中,接口可以看作是多个类的公共规范,符合这个规范的类都可以引用这个接口。

1.3 接口是一种引用数据类型。

2. 接口的语法:

2.1 接口的定义:

接口的定义与类的定义基本一致,将class换成interface就定义了一个接口:

//public interface 接口名称 {
//......
// }
//接口的命名一般以大写字母I开头,即Ixxx
public interface IUsb {
//xxx
}

//这就定义好了一个叫Usb的接口

2.2 接口中的成员变量:

接口中的成员变量默认有public stasic final (可以不写) 修饰着:

public interface IUsb {
    int a = 10;
    public static final int b = 100;
    //此时变量a的前面默认是有public static final修饰着。
    //变量a和变量b类型是一致的。
}

2.3 接口中的方法

1. 接口中的方法都是抽象方法:

public interface IUsb {
    //接口中的方法默认被public abstract 修饰,所以接口中的方法都是抽象方法,不需要实现。

    void function1();
    public abstract void function2();

    //此时方法function1的前面默认是有 public abstract 修饰
    //此时方法function1和方法function2的类型是一致的
  }

2. 接口中的方法能实现的操作:
接口中的方法被default修饰时,可以有具体的实现:

public interface IUsb {
    default void function(){
        //....
    }
 }

接口中的方法被static修饰时,可以有具体的实现:

public interface IUsb {
    static void function(){
        //....
    }
 }

注:被defaul和static修饰的方法不是抽象方法。

2.4 接口的实现:

一个类要实现一个接口,需要implements关键字:

public class 类 implement 接口 { ... }

1. 当一个普通类实现一个接口时,必须要重写接口中所有的抽象方法:

//接口
public interface Iusb {
    void function1();
    
    void function2();
}
//类
class Test implements Iusb{

     @Override
     public void function1() {
         
     }

     @Override
     public void function2() {

     }
 }

补充:实现那接口中抽象方法的快捷键:将光标移到红线那里,然后Alt + Enter

2. 当一个抽象类继承一个接口时,可以不用重写接口中的抽象方法:

此时代码没有报错,说明通过了编译。

3. 当一个普通类继承了一个抽象类,且这个抽象类还实现了一个接口时,普通类要同时重写抽象类和接口中所有的抽象方法:

//接口
public interface Iusb {
    void function1();

    void function2();
}
//抽象类
 abstract class Test implements Iusb{
     public abstract void method();
}
//普通类
class Demo extends Test {
    @Override
    public void function1() {
    }
    @Override
    public void function2() {
    }
    @Override
    public void method() {
    }
}

2.5 实现多个接口:

一个类只能继承一个父类;但一个类可以实现多个接口,表示这个类同时具有多种特性。

语法:public class 类 implement 接口,接口,... { ... }

interface IRunning {
    void run();
}
interface ISwimming {
    void swim();
}

public class Duck implements ISwimming,IRunning{
    private String name = "贞德是你呀";
    @Override
    public void run() {
        System.out.println(this.name + "正在跑");
    }

    @Override
    public void swim() {
        System.out.println(this.name + "正在游泳");
    }
}
//类Duck实现了IRunning,ISwimming 接口,那么Duck就具有了这两个接口的功能,但还没有实现
//然后Duck在自己类中要去重写这两个接口中的抽象方法,即去实现这run和swim这两个功能

2.6 接口的继承:

接口之间可以多继承,接口的继承相当与把多个接口合并在一起,达到代码的复用。

用关键字extends实现接口的多继承。

interface IRunning {
    void run();
}
interface ISwimming {
    void swim();
}

public interface IAmphibian extends IRunning,ISwimming{

}

class Frog implements IAmphibian{
    @Override
    public void run() {
    }
    @Override
    public void swim() {

    }
}
//IAmphibian(两栖动物)接口继承了IRunning和ISwimming接口
//当Frog(青蛙)类实现了Amphibian接口时,就同时实现了IRunning和ISwimming接口
//就不用Frog在去实现两个接口,实现一个接口就可以了,实现了代码的复用

补充:1. 接口不能被实例化(这点与抽象类一致)。

           2.子类中重写接口中的抽象方法时的访问修饰限定符的权限大小不能小于接口中方法的权限的大小。

三:接口的应用

实现一个电脑通过USB接口来控制鼠标、键盘的代码 (其中的过程更像是一种多态的思想)

3.1 鼠标和键盘实现USB接口

class Mouse implements IUsb{
    @Override
    public void openDevice() {
        System.out.println("打开鼠标!");
    }
    @Override
    public void closeDevice() {
        System.out.println("关闭鼠标!");
    }
    //类中自己的方法
    public void click() {
        System.out.println("点击鼠标!");
    }
}

class KeyBoard implements IUsb{
    @Override
    public void openDevice() {
        System.out.println("打开键盘!");
    }
    @Override
    public void closeDevice() {
        System.out.println("关闭键盘!");
    }
    public void inPut(){
        System.out.println("键盘输出");
    } 
}
public interface IUsb {
    void openDevice();

    void closeDevice();
}

3.2 电脑能够使用USB设备

即存在调用接口的方法

class Computer {
    //在Computer类中使用USB接口
    public void powerOn() {
        System.out.println("打开电脑");
    }
    public void powerOff() {
        System.out.println("关闭电脑");
    }

    //这个接口类的参数能接收实现了该接口的类(多态思想中的向上转型)
    public static void useDevice(IUsb usb) {
        //通过多态思想调用的方法都是接口中的共性方法(抽取多个类中共同拥有的方法)
        usb.openDevice();//此时的usb就是你所调用的类的对象 (多态思想中的动态绑定)
        //instanceof关键字是用来判断usb中的对象是否是Mouse
        if (usb instanceof Mouse){
            //若想调用类自己的方法,则是需要本类的类的对象引用来调用
            Mouse mouse = (Mouse) usb;//usb中存的是通过向上转型上来的类的对象,此时只需要对usb向下转型即可
            mouse.click();
        }else if (usb instanceof KeyBoard) {
            KeyBoard keyBoard = (KeyBoard) usb;
            keyBoard.inPut();
        }
        usb.closeDevice();
    }
}

3.3 测试 

即电脑进行接口当中的操作

class TestUsb {
    public static void main(String[] args) {
        Computer computer = new Computer();
        computer.powerOn();

        //接口要使用类,那这个接口就得存在这个类,即给这个接口一个类的对象
        //使用鼠标
        computer.useDevice(new Mouse());
        //使用键盘
        computer.useDevice(new KeyBoard());

        computer.powerOff();

    }
}

注:接口的使用蕴含着多态思想

  • 58
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值