前言在Java面向对象编程中抽象类接口内部类以及Object类是构建灵活可拓展代码的核心工具。理解它们的区别与联系掌握使用场景是每一位Java开发者进阶的必经之路。本文将结合通俗易懂的案例带你彻底搞懂抽象类的概念语法和特性接口的定义多实现与继承Object类的常用方法toStringequals各种内部类的使用静态内部类实例内部类局部内部类匿名内部类抽象类与接口的核心区别目录前言一.抽象类1.1为什么需要抽象类1.2抽象类语法1.3抽象类特性1.4抽象类的作用二.接口2.1接口的概念2.2接口语法2.3接口的实现2.4接口特性2.5实现多个接口2.6接口间的继承2.7接口使用实例对象比较2.8Cloneable接口与深拷贝三.抽象类VS接口四.Object类4.1toString——获取对象信息4.2equals()——对象比较五.内部类5.1静态内部类5.2实例内部类非静态5.3局部内部类5.4匿名内部类六,总结一.抽象类1.1为什么需要抽象类在面向对象的世界里所有对象都是通过类来描述的。但有些类并不具体无法描述一个真实对象。比如Shape图形——它只是一个概念无法画出具体的形状Animal动物——它只是一个统称无法让动物发出具体的叫声这些类缺少足够的信息来描述对象因此应该被设计为抽象类抽象类就像一张设计图纸不能直接拿来住人但是可以知道建造具体的房子。1.2抽象类语法使用abstract关键字修饰列和方法public abstract class Shape{ //抽象方法没有方法体必须由子类实现 public abstract void draw(); //抽象类可以有自己的属性和普通方法 private double area; public double getArea(){ return area; } }1.3抽象类特性1.不能实例化Shape shape new Shape(); //编译错误2.抽象方法不能是private ,fianl,staticabstract private void test(); // 错误 abstract final void test2(); // 错误 abstract static void test3(); // 错误3.子类必须重新给所有抽象方法否则子类也必须声明为抽象类public class Cricle extends Shape{ Override public void draw (){ System.out.println(画一个圈); } }4.抽象类可以有构造方法供子类调用初始化父类成员5.抽象类不一定包含抽象方法但抽象方法的类一定是抽象类1.4抽象类的作用抽象类存在的最大意义多一层编译器的校验。如果某个方法不应该由父类实现而必须由子类实现那么将其声明为抽象方法父类声明为抽象类。这样一旦由人误用父类实例化编译器立即就会报错避免逻辑错误。二.接口2.1接口的概念接口是一种公共的行为规范。只要符合规范不同设备都可以通用。再Java中接口是一种引用数据类型是多个类的公共规范2.2接口语法public interface USB{ //接口中的变量默认是 public static final double VERSION 3.0 //方法默认是public abstract void openDevice(); }2.3接口的实现使用implements关键字一个类可以实现多个接口。public class Mouse implements USB { Override public void openDevice() { System.out.println(打开鼠标); } Override public void closeDevice() { System.out.println(关闭鼠标); } }2.4接口特性1.不能直接实例化2.所有方法默认public abstractJava 8后可以有default和static方法3.变量默认public static final4.没有构造方法5.一个类可以实现多个接口弥补了单继承的不足2.5实现多个接口class Frog extends Animal implements IRunning, ISwimming { Override public void run() { System.out.println(name 正在跳); } Override public void swim() { System.out.println(name 正在游泳); } }2.6接口间的继承接口可以多继承使用extendsinterface IAmphibious extends IRunning, ISwimming { }这样IAmphibious就合并了IRunning和ISwimming两个接口的方法。2.7接口使用实例对象比较方式一实现Comparable接口class Student implements ComparableStudent{ private String name; private int score; Override public int compareTo(Student o){ return this.score-o.score; } }方式二Comparator接口class ScoreComparator implements ComparatorStudent { Override public int compare(Student o1, Student o2) { return o1.score - o2.score; } }2.8Cloneable接口与深拷贝Cloneable是一个标记接口没有任何方法用于告诉JVM该类可以安全地克隆class Person implements Cloneable { public Money money new Money(); Override protected Object clone() throws CloneNotSupportedException { return super.clone(); // 浅拷贝 } }浅拷贝只拷贝对象本身内部引用类型成员仍然指向同一个对象。深拷贝需要手动实现拷贝递归所有类型成员三.抽象类VS接口对比项抽象类接口关键字abstract classinterface实例化不能不能构造方法可以有不能有不同方法可以有Java8前不能之后可以有default/static方法成员变量各种访问权限默认private static final继承/实现单继承多实现使用场景表示“是什么”表示“能做什么”核心区别抽象类可以包含普通方法和成员变量子类可以直接复用接口只定义规范子类必须全部实现。四.Object类所有类都直接或间接继承Object它是类层次结构的根4.1toString——获取对象信息System.out.println(obj); // 默认调用 obj.toString()默认实现类名哈希码的十六进制。通常需要重写以返回有意义的描述。4.2equals()——对象比较默认比较地址和一样。若要比较内容必须重写Override public boolean equals(Object obj) { if (this obj) return true; if (obj null || getClass() ! obj.getClass()) return false; Person person (Person) obj; return age person.age Objects.equals(name, person.name); }五.内部类内部类是指定义在另一个内部的类。它也是一种封装形式。5.1静态内部类被static修饰只能访问外部类的静态成员。public class OutClass { static class InnerClass { public void method() { // 只能访问外部类的静态成员 } } } // 创建 OutClass.InnerClass inner new OutClass.InnerClass();5.2实例内部类非静态可以访问外部类的任何成员。创建时需要先有外部类实例。public class OutClass { class InnerClass { public void method() { // 可以直接访问外部类成员 } } } // 创建 OutClass out new OutClass(); OutClass.InnerClass inner out.new InnerClass();5.3局部内部类定义在方法内部只能再方法内使用不能使用访问修饰符。public void method() { class LocalClass { // ... } LocalClass lc new LocalClass(); }5.4匿名内部类没有名字在创建的同时之间实现接口或继承类。常用于一次性使用的场景。Greeting greeting new Greeting() { Override public void greet() { System.out.println(Hello!); } }; greeting.greet();匿名内部类可以访问外部类的成员以及所在方法的final或effectively final的局部变量。六,总结抽象类用来表示“一种类型”可以有部分实现子类通过继承复用代码。接口用来表示“能力/规范”强调“能做什么”实现类需要全部实现Object类所有类的父类牢记toSringequals的重写规则。内部类根据位置和修饰符分为四种匿名内部类在GUI编程事件监听中极为常用。