大白话!Java中的抽象类和接口的理解!

发布时间:2026/10/12 2:25:12
大白话!Java中的抽象类和接口的理解!
1. 什么是抽象类在java面向对象的概念中所有的对象都是通过类来描绘的但是反过来并不是所有的类都是用来描绘对象的如果有一个类中没有包含足够信息来描绘一个具体的对象这样的类就是抽象类。如上图所示正方形类、圆形类、三角形类都是图形类的子类但是图形类Shape并不是具体的图形其内部的draw其实是没有办法实现的后续会提到是为什么由于Shape类没有办法描述一个具体的图形导致draw()方法无法具体实现因此我们可以将Shape设计为“抽象类”。由上图我们不难发现父类Shape中的draw方法貌似没有什么用像这种没有实际工作的方法我们可以把它设计成一个抽象方法(abstract method)包含抽象方法的类我们就叫做抽象类(abstract class)1.1 抽象类的语法public abstract class Shape{ abstract public void draw(); abstract void Area(); //不难看出上面这些方法都是被abstract修饰的而且都没有具体的实现过程 public double getArea(){ return 3.14*3.14; } public int a; //抽象类中也可以由类中的普通变量和成员方法 }1.2 抽线类的特性抽象类不能直接实例化对象抽象类不能new抽象类不能是private的抽象方法不能被final和static修饰因为抽象方法要被子类重写抽象类必须被继承并且继承后的子类要重写父类中的抽象方法否则子类也是抽象类必须要被abstract修饰抽象类不一定要包含抽象方法但是抽象方法的类一定是抽象类抽象类中可以有构造方法供子类创建对象时初始化父类的成员变量1.2.1 具体代码实现public class Test { public abstract class Shape{ abstract private void draw(); //报错非法修饰符组合 abstractprivate abstract final void Area(); //报错如果抽象类的方法被final 和 static 修饰那么子类就 无法继承了 public double getArea(){ return 3.14*3.14; } public int a; } public static void main(String[] args) { Shape shapenew Shape(); //直接报错Shape是抽象类不能被实例化 } }//抽象类 public abstract class Shape{ abstract public void draw(); abstract void Area(); // public double getArea(){ return 3.14*3.14; } public int a; } //矩形子类 public class Rect extends Shape{ private double width; private double height; Rect(double width, double height){ this.width width; this.height height; } //这两个抽象方法必须要被重写少一个都报错 Override public void draw() { System.out.println(Drawing rect); } Override void Area() { System.out.println(Area rect); } } //三角形子类 public abstract class Triangle extends Shape{ private double a; private double b; private double c; Override public void draw() { System.out.println(Drawing triangle); } Override void Area(); //报错没有重写父类抽象类中的方法Triangle被abstrac修饰 }1.3 抽象类的作用抽象类本身并不能被实例化吗但是想要使用只能创造该抽象类的子类然后用子类来实现抽象类中的抽象方法。问这样是不是太复杂了普通类也可以被继承呀普通的方法也可以被重写呀为啥非得用抽象类的抽象类呢感觉就是没事找事啊。答确实但是抽象类相当于多了一重校验器。使用抽象类的场景就如上面的代码实际工作不应该由父类完成而应是用子类完成。如果这个时候不小心用成了父类使用普通的编译器是不会报错的但是父类是抽象类就会在实例化的时候提示你有问题。顺带一提很多语法存在的意义即使未来预防出错我们之前用过的final也是创建的变量如果被修改们就会提示你有问题需要检查在实际中我们可以充分利用编译器的校验在实际的开发工作中还是十分有用的2. 什么是接口在我们日常生活中接口随处可见例如插座接口电脑USB接口由上面的图片不难得出接口就是公共行为的规范标准在实现时只要符合规范标准就可以通用2.1 语法规则接口的定义格式与类的定义格式基本相同将class关键字换成interface关键字这就定义了一个接口。创建接口时接口的命名一般以大写字母 I i) 开头。接口的命名一般使用形容词性的单词。阿里编码规范中约定接口中的方法和属性不要加任何修饰符号保持代码的简洁性2.1.1 具体代码实现public interface Itest { public abstract void method1(); //public abstract 是固定搭配可以不写 public void method2(); abstract void method3(); void method4(); //注意在接口中上述的写法都是抽象方法但是推荐些方法4代码更加简洁~ }2.2 接口的使用接口不能直接使用必须要有一个”实现类“来”实现“该接口实现接口的所有抽象方法。基本语法public class 类名称 implements接口名称{ //... }2.2.1 具体的代码实现【注意】子类和父类之间是extends继承关系类与接口之间是implements实现关系//USB接口类 public interface USB{ void openDevice(); void closeDevice(); }//鼠标类 public class Mouse implements USB{ Override public void openDevice() { System.out.println(Opening mouse device); } Override public void closeDevice() { System.out.println(Closing mouse device); } public void click(){ System.out.println(Clicking on mouse device); } }//键盘类 public class keyBoard implements USB{ Override public void openDevice() { System.out.println(Opening keyboard device); } Override public void closeDevice() { System.out.println(Closing keyboard device); } public void input() { System.out.println(Entering keyboard device); } }//笔记本类使用USB设备 public class Computer{ public void powerOn(){ System.out.println(Power on computer); } public void powerOff(){ System.out.println(Power off computer); } 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(); } }2.3 接口的特性演示代码接口类型是一种引用类型但是不能直接new接口对象这点和抽象类是一样的public class TestUSB { public static void main(String[] args) { USB usbnew USB(); //报错USB不能被new } }2.接口中每一个方法都是public的抽象方法public interface USB{ private void openDevice();//private不能再接口中实现 void closeDevice(); }3.接口中的方法是不能在接口中实现的只能由实现接口的类来实现抽象类中被abstract修饰的方法同样不能在抽象类中实现//USB接口类 public interface USB{ void openDevice(); void closeDevice(); //报错不能在接口中实现接口定义的方法 void openDevide(){ System.out.println(Opening device using USB); } }4.重写接口方法时不能使用默认的访问权限//鼠标类 public class Mouse implements USB{ Override void openDevice() { System.out.println(Opening mouse device); } //报错正确写法是要在前面加上public /*原因原来在接口中定义的是 void openDevice()默认的就是包访问权限现在在类中要 特地强调public的访问范围*/ }5.接口中可以含有变量但是接口的变量会被隐式指定为public static final变量//USB接口类 public interface USB{ double brand10.0; void openDevice(); void closeDevice(); } //测试类 public class TestUSB { public static void main(String[] args) { System.out.println(USB.brand); USB.brand1.0;// 报错提示brand被final修饰不能更改 } }6.接口中不能有静态代码块和构造方法//USB接口类 public interface USB{ double brand10.0; void openDevice(); void closeDevice(); //构造方法 public USB{ //报错 } //代码块 { //报错 } }7.接口不是类但是完成接口编译后的字节码文件后缀格式也是.class8.如果类没有实现接口中的所有抽象方法则类必须设置为抽象类9.jdk8中接口还可以包含default方法2.4 实现多个接口在JAVA中类和类之间是单继承的一个类中只能由一个父类JAVA不支持多继承一个类有多个父类但是一个类可以实现多个接口。2.4.1 代码演示众所周知鸭子是“水陆空”的全能战士我们可以创造分别对应着的“游泳”、“飞翔”、“跑步” 三个接口在创建duck类去进行调用【注意】在调用多个接口时要对接口中的每一个抽象方法进行实现否则该类必须设置为抽象类public interface IFlying { void fly(); }public interface IRuning { void run(); }public interface ISwimming { void swim(); }class Animal{ protected String name; public Animal(String name) { this.name name; } } //继承父类Animal 还有对三个接口的调用 class Duck extends Animal implements IRuning, ISwimming ,IFlying{ public Duck(String name) { super(name); } Override public void run() { System.out.println(this.name正在用四条腿跑步); } Override public void fly() { System.out.println(this.name正在用翅膀飞); } Override public void swim() { System.out.println(this.name正在水里游); } }鸭子【友情提示】在IDEA平台上可以使用ctrli的方式快速实现接口2.5 接口之间的继承在Java中类和类之间都是单继承的一个类可是实现多个接口接口与接口之间可以多继承即用接口可以达到多继承的目的使用关键字extends2.5.1 代码演示//两栖动物既可以跑也可以游 public interface IAmphibious extends IRuning,ISwimming { void run(); void swim(); }青蛙美西螈2.6 接口使用的案例对象之间进行大小关系比较class Student { String name; int age; public Student(String name, int age) { this.name name; this.age age; } Override public String toString() { return Student{ name name \ , age age }; } } public class Test2 { public static void main(String[] args) { Student s1new Student(张三,18); Student s2new Student(李四,19); System.out.println(s1s2);//编译报错 } }在编译器运行时会发生报错因为我们指定它是根据分数比较还是其他什么比较。所以我们应该指定以什么方式进行比较但是不太好的一点就是按照这样的方式比较后不灵活。无法按照其他的方式进行比较。2.6.1 使用Comparable接口class Student implements Comparable { private String name; private int age; public Student(String name, int age) { this.name name; this.age age; } Override public String toString() { return Student{ name name \ , age age }; } Override public int compareTo(Object o) { Student s (Student) o; if (this.age s.age) { return -1; }else if (this.age s.age) { return 1; }else{ return 0; } } } public class Test2 { public static void main(String[] args) { Student s1new Student(张三,18); Student s2new Student(李四,19); System.out.println(s1.compareTo(s2)); } }如果s1大于s2那么返回大于0的数字如果相同则返回0否则返回小于0的数字2.6.2 使用Comparator接口import java.util.Comparator; class Student { public String name; public int age; public Student(String name, int age) { this.name name; this.age age; } Override public String toString() { return Student{ name name \ , age age }; } } // Student里面的内容表示只能用来比较Student类型里面的对象 class AgeComparator implements ComparatorStudent { Override public int compare(Student o1, Student o2) { return o1.age-o2.age; } } class NameComparator implements ComparatorStudent { Override public int compare(Student o1, Student o2) { return o1.name.compareTo(o2.name); } } public class Test2 { public static void main(String[] args) { Student s1new Student(zhangsan,18); Student s2new Student(lisi,19); //年龄比较 AgeComparator ageComparatornew AgeComparator(); System.out.println(ageComparator.compare(s1,s2)); //姓名比较 NameComparator nameComparatornew NameComparator(); System.out.println(nameComparator.compare(s1,s2)); } }3. 抽象类和接口的区别核心区别抽象类中可以包含普通方法和普通字段这样的普通方法和字段可以被子类对象直接使用不必重写而接口中不能包含普通字段子类必须重写所有的抽象类。其他区别抽象类用abstract class 接口用 interface一个类可以继承一个抽象类但是可以实现多个接口也接口支持多实现继承抽象类用extends实现接口用implements