首页 > 编程语言 >Java----抽象类与接口

Java----抽象类与接口

时间:2024-07-20 17:26:25浏览次数:11  
标签:Java name void 接口 ---- println 抽象类 public

知识框架:


 一. 抽象类


1.1 抽象类的概念

  在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。如下图所示:

说明:

  Animal类是动物类,每个动物都有叫的方法,但是Animal不是一个具体的动物,因此其内部的bark()方法无法具体实现。Dog是狗类继承Animal类,狗是一个具体的动物,狗叫'' 旺旺 '',其bark()可以实现。Cat是猫类继承Animal类,猫是一个具体的动物,猫叫'' 喵喵 '',其bark()可以实现。因此Animal可以设计为'' 抽象类 ''。换言之:没有实际工作的方法,我们可以把它设计为抽象方法,包含抽象方法的类称为'' 抽象类 ''。


 1.2 抽象类的语法

  在Java中被 abstract 修饰的类称为抽象类,在抽象类中被abstract修饰的方法被称为抽象方法,抽象方法不能给出具体的实现体。

public abstract class Animal {     //抽象类,被abstract修饰
    abstract void eat();           //抽象方法,被abstract修饰没有方法体
    abstract void sleep();
    public void run(){             //也可以增加普通方法和属性
        System.out.println("跑");
    }
}

注意:抽象类可以包含普通方法和属性和构造方法。

1.3 抽象类特性

1.3.1抽象类不能直接实例化对象。

 Animal animal = new Animal();
 //编译报错,因为Animal是抽象的无法实例化

 

1.3.2抽象方法不能被private  final  static 修饰。

 abstract private void eat();  
 //编译报错,非法的修饰符组合:abstract和private
 abstract final void eat();    
 abstract static void sleep();
 //编译报错,非法的修饰符组合


 总结:

  抽象方法不能被private  final  static 修饰的原因:抽象类必须被继承,并且被继承后子类要重写父类中所有的抽象方法(子类是抽象类除外)。

  注意:抽象方法没有加访问修饰符,默认是public。

1.3.3抽象类必须被继承,并且被继承后子类要重写父类中所有的抽象方法,子类也是抽象类可以不重写,否则必须要用abstract修饰

请看如下代码: 

public abstract class Animal {     
    abstract void eat();           
    abstract void sleep();
    
}
 
 
 
public class Dog extends Animal {
    @Override
    void eat() {
    }
 
    @Override
    void sleep() {
    }
}
 
 
 
public abstract class Cat extends Animal{
    @Override
    void eat() {
        
    }
}

1.3.4 抽象类中不一定包含抽象方法,但是有抽象方法的类一定是抽象类。
1.3.5 抽象类中可以有构造方法,供子类创建对象时,初始化父类的成员变量。

1.4抽象类存在的意义

  使用抽象类,实际工作由子类完成;像普通类不小心new父类对象了,编译器很难发现问题所在,但是父类是抽象类在实例化的时候编译器会提示错误,对代码做了更好的校验相当于多了一次代码检查工作,让开发者尽早发现问题所在。



 

二. 接口

2.1 接口的概念

  现实生活中接口的例子很多,比如电脑上的USB接口,电源插座等。电脑的USB口可以插:U盘,鼠标键盘,所有符合USB协议的设备,电源的插座可以插:电脑,电视机,电饭煲,所有符合规范的设备。

上述例子可以看出:接口就是公共的行为规范标准,大家在实现时,只要符合标准就可以通用。在Java中,接口可以看成多个类的公共规范,是一种引用数据类型。

2.2 语法规则

访问修饰符 interface  接口名 {

  

}

请看如下代码: 

public interface 接口名称{
    public abstract void method1();   //public abstract是固定搭配,可以省略不写
    public void method2();
    abstract void method3();
    void method4();       //推荐这种风格
}

说明:

  1. 创建接口时,接口的命名一般以大写字母I开头
  2.  接口命名一般使用形容词词性的单词
  3. 阿里编码规范中规定,接口中的方法属性不要加任何修饰符号,保持代码的简洁性

2.3 接口使用 

  接口不能直接实例化,必须有一个实现类来实现接口中的所有抽象方法,这里使用关键字implements来实现。

public class 类名称 implements 接口名称{
       //......
}

 注意:子类父类是extends继承关系,类与接口之间是implements实现关系。

请看如下案例:
实现笔记本电脑使用USB鼠标,USB键盘。
1.USB接口:包含打开设备,关闭设备功能。
2.笔记本类:包含开机功能,关机功能,使用USB设备功能。
3.鼠标类:实现USB接口,并具备点击功能。
4. 键盘类:实现USB接口,并具备输入功能。
 

请看如下代码:

//USB接口
public interface USB {
    void openDevice();
    void closeDevice();
}
 
//鼠标类
public class Mouse implements USB{
    @Override
    public void openDevice() {
        System.out.println("打开鼠标");
    }
 
    @Override
    public void closeDevice() {
        System.out.println("关闭鼠标");
    }
    public void click(){
        System.out.println("点击鼠标");
    }
}
 
//键盘类
public class KeyBoard implements USB{
    @Override
    public void openDevice() {
        System.out.println("打开键盘");
    }
 
    @Override
    public void closeDevice() {
        System.out.println("关闭键盘");
    }
    public static void inPut(){
        System.out.println("键盘输入");
    }
}
 
//电脑类使用USB设备
public class Computer {
    public void powerOn(){
        System.out.println("打开笔记本电脑");
    }
    public void powerOff(){
        System.out.println("关闭笔记本电脑");
    }
    public void useDevice(USB usb){
        usb.openDevice();
        if(usb instanceof Mouse){
            Mouse mouse = (Mouse)usb;
            mouse.click();
        }else if(usb instanceof KeyBoard){
            KeyBoard keyboard = (KeyBoard)usb;
            KeyBoard.inPut();
        }
        usb.closeDevice();
    }
}
 
//测试类
public class TestUSB {
    public static void main(String[] args) {
        Computer computer = new Computer();
        computer.powerOn();
        computer.useDevice(new Mouse());
        computer.useDevice(new KeyBoard());
        computer.powerOff();
    }
}
 

 1: 接口不能直接实例化。

public class TestUSB {
    public static void main(String[] args) {
        USB usb = new USB() ;     //编译报错:USB是抽象的,无法实例化
}

2. 接口中的抽象方法都是public的抽象方法,重写该抽象方法时访问权限必须是public。

3. 接口中的方法不能有具体的实现。

请看如下代码:

public interface USB {
    void openDevice();
    void closeDevice(){
        System.out.println("关闭设备");      //编译错误,接口中的方法默认为抽象方法
    }
}

5.接口中可以含有变量,但接口中的变量会被隐式的指定为public static final 变量。

6.接口中可以有默认方法,静态方法。

public interface ITest {
    int size = 10;//public static final

    void draw();//public abstract

    default public void func() {    //默认方法不需要重写
        System.out.println("默认方法!");
    }

    public static void func2() {       //静态成员方法不需要重写
        System.out.println("你好");
    }

4.重写接口方法时不能使用default访问权限修饰符,因为子类重写的方法的访问权限要大于等于父类方法访问权限。 

6.接口中不能有静态代码块和构造方法。

7.接口虽然不是类,但是编译完成后的字节码文件的后缀也是.class。

8.如果类没有实现接口中的所有抽象方法,则类必须设置为抽象类。

2.4 实现多个接口 

 在Java中类是单继承的,但是一个类可以实现多个接口,解决了java当中不支持多继承的缺陷。


下面通过类表示一组动物

public class Animal {
    protected String name;
 
    public Animal(String name) {
        this.name = name;
    }
}
public interface ISwimming {
    void swim();
}
 
public interface IFlying {
    void fly();
}
 
public interface IRunning {
    void run();
}
public class Cat extends Animal implements IRunning{
    public Cat(String name){
        super(name);
    }
 
    @Override
    public void run() {
        System.out.println(this.name+"正在跑");
    }
}
public class Fish extends Animal implements ISwimming{
    public Fish(String name){
        super(name);
    }
 
    @Override
    public void swim() {
        System.out.println(this.name+"正在游");
    }
}

public 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+"正在游");
    }
}

注意:一个类在实现接口时,每个接口的抽象方法都要实现,否则必须设置成抽象类。


鸭子:水陆空三栖动物

public class Duck extends Animal implements ISwimming,IRunning,IFlying{
    public Duck(String name){
        super(name);
    }
 
    @Override
    public void fly() {
        System.out.println(this.name+"在空中飞");
    }
 
    @Override
    public void run() {
        System.out.println(this.name+"在地上跑");
    }
 
    @Override
    public void swim() {
        System.out.println(this.name+"在水里游");
    }
}

 2.5 接口间的继承

  在Java中类与类之间是单继承的,一个类可以实现多个接口,接口与接口之间可以多继承。

public interface IRunning {
    void run();
}
 
public interface ISwimming {
    void swim();
}
 
public interface IAmphibious extends IRunning,ISwimming{
    
}
class Frog implements IAmphibious{
    
}

  通过接口继承,创建一个新的接口IAmphibious表示'' 两栖的 '',此时实现接口创建的Frog类要实现run方法,还要实现swim方法。

2.6 接口之间的实例

给对象数组排序

public class Student {
    private String name;
    private int score;
 
    public Student(String name, int score) {
        this.name = name;
        this.score = score;
    }
 
    @Override
    public String toString() {
        return "["+this.name+":"+this.score+"]";
    }

  在给定一个学生对象数组,对这个数组中的元素进行排序

Student[] students = new Student[] {
                new Student("张三",92),
                new Student("李四",94),
                new Student("王五",90),
        };

 

   数组有一个sort方法,能否直接用这个方法呢?

  Arrays.sort(students);    //编译报错
        System.out.println(Arrays.toString(students));

普通整数可以直接比较,而两个学生对象的大小关系需要额外指定,让Student类实现Comparable接口,并实现该接口中的compareTo()方法。

 

public class Student implements Comparable{
    private String name;
    private int score;
 
    public Student(String name, int score) {
        this.name = name;
        this.score = score;
    }
 
    @Override
    public String toString() {
        return "["+this.name+":"+this.score+"]";
    }
    @Override
    public int compareTo(Object o){
        Student s = (Student)o;
        if(this.score>s.score){
            return -1;
        }else if(this.score<s.score){
            return 1;
        }else {
            return 0;
        }
    }

 

compareTo的参数是Object,传入的是Student类的对象,然后比较当前对象和参数对象的大小关系(按分数来算)。

· 如果当前对象应排在参数对象之前,返回小于0的数字。

· 如果当前对象应排在参数对象之后,返回大于0的数字。

· 如果当前对象和参数对象不分前后,返回0。

注意事项:对于sort来说,需要传入的数组的每个对象都是可比较的,需要具备compareTo这样的能力,通过重写compareTo就可以定义比较规则。

2.7 抽象类和接口的区别 

  抽象类和接口都是Java中多态的常见使用方式,二者都能增强代码的复用性和可扩展性。

  主要区别:抽象类中可以包含普通字段和普通方法,这样的字段和方法可以被子类直接使用(不必重写),接口中不能包含普通方法(可以包含默认方法),子类必须重写其所有抽象方法。

   抽象类的存在是为了让编译器更好的校验,像Animal这样的类我们不会直接使用,而是直接使用子类,如果不小心创建了Animal实例,编译器会及时提醒我们

标签:Java,name,void,接口,----,println,抽象类,public
From: https://blog.csdn.net/C384136844/article/details/140529066

相关文章

  • ETCD DB SIZE不一致问题
    问题1、dbsize和定期压缩有关。压缩事件是由apiserver触发的。2、RAFTTERM|RAFTINDEX|RAFTAPPLIEDINDEX3个一致就好了kube-apiserver-h|grepcompaction-interval--etcd-compaction-intervaldurationTheintervalofcompactionrequests.......
  • 基于Matlab的数据可视化
    基于Matlab的数据可视化一、二维图形的绘制(一)基本图形函数(1)plot函数(2)fplot函数(3)其他坐标系的二维曲线(二)图形属性设置(1)线型、标记、颜色(2)图形标注(支持LaTex中公式、符号的输入)(3)坐标控制二、三维图形的绘制(一)三维曲线(1)plot3()(2)fplot3()(二)三维曲面(1)平面网格数据的生成......
  • PG参数深入了解
    目录shared_buffers作用:配置建议:示例配置:work_memmaintenance_work_memautovacuum_work_memeffective_cache_size计算规格:注意事项:wal_buffersshared_buffersshared_buffers是PostgreSQL数据库配置文件postgresql.conf中的一个重要参数,它用于设置数据库服务......
  • SciTech-Theory-Phenomeon(Process and its Outcomes)->Experience(Sensation+Cogniti
    SciTech-Theory:Objective:Phenomeon:aobjectiveProcessanditsOutcomesSubjective:->Experience:Sensation+Cognition->Concept(Natural+Commonpartofexperiences)->Principle(research+invest)->Interpretations->Definition->Theo......
  • Maven生命周期和Maven多环境配置
    一、Maven功能Maven是专门用于管理和构建Java项目的工具,它的主要功能有:1.提供了一套标准化的项目结构(eclipse和MyEclipse,idea通用的) Maven提供了一套标准化的项目结构,所有IDE使用Maven构建的项目结构完全一样,所有IDE创建的Maven项目可以通用2.提供了一......
  • JAVA 数据结构 - 数组
    一、固定数组Arrays数组用来存储固定大小的同类型的元素;1、声明,初始化,访问int[]myIntArray;double[]myDoubleArr;String[]myStrArr;intsize=10;double[]myDoubleArr=newdouble[size];double[]myList={1.9,1.4,2.3,9.8};for(inti=0;i<myList.le......
  • ComfyUI进阶:Comfyroll插件 (五)
    ComfyUI进阶:Comfyroll插件(五)前言:学习ComfyUI是一场持久战,而Comfyroll是一款功能强大的自定义节点集合,专为ComfyUI用户打造,旨在提供更加丰富和专业的图像生成与编辑工具。借助这些节点,用户可以在静态图像的精细调整和动态动画的复杂构建方面进行深入探索。Comfyroll的节点设......
  • 代码随想录算法训练营第33天 | 贪心4:452. 用最少数量的箭引爆气球、435. 无重叠区间
    代码随想录算法训练营第33天|贪心4:452.用最少数量的箭引爆气球、435.无重叠区间、763.划分字母区间452.用最少数量的箭引爆气球https://leetcode.cn/problems/minimum-number-of-arrows-to-burst-balloons/description/代码随想录https://programmercarl.com/0452.用最......
  • 第三周总结
    学习时间:每天3h代码量:每日300行今日进行放假的测试石家庄铁道大学2024年夏季  2022级课堂测试试卷—Hadoop数据库应用课程名称:大型数据库应用技术 任课教师:王建民  考试时间:实现为止分钟  一、    测试题目1、完成科技查新基本信息填报功能,基本信息如下所示......
  • Handbook of Enumerative Combinatorics 阅读
    Chapter1代数几何方法1.3生成函数符号化方法和拉格朗日反演拆分数的生成函数和五边形数定理、斐波那契的拆分数平面二叉树(PlaneBinaryTree)、三角剖分、DyckPath的等价和双射及k叉金字塔结构(没有认真看)用循环来统计排列——错排列和内卷排列(involution):\[\sum_{i\ge......