1 Java内部类
1.1 概念
在 Java 中,内部类是指定义在另一个类内部或方法内部的类。内部类可以分为以下几种类型:
- 成员内部类
- 局部内部类
- 匿名内部类
- 静态内部类
1.2 成员内部类
- 定义:成员内部类是最常见的内部类,它定义在外部类的成员位置。
- 访问权限:成员内部类可以无限制地访问外部类的所有成员属性,包括私有成员。
- 创建对象:外部类需要先创建一个成员内部类的对象,才能访问内部类的成员。
- 示例:
class Outer {private int outerVar = 10;class Inner {void display() {System.out.println("Outer variable: " + outerVar);}} }public class Main {public static void main(String[] args) {Outer outer = new Outer();Outer.Inner inner = outer.new Inner();inner.display();} }
1.3 局部内部类
- 定义:局部内部类定义在一个方法或作用域内,其生命周期仅限于该作用域。
- 访问权限:局部内部类不能被权限修饰符(如
public
、protected
、private
、static
)修饰。 - 示例:
class Outer {void method() {class LocalInner {void display() {System.out.println("Local Inner Class");}}LocalInner localInner = new LocalInner();localInner.display();} }public class Main {public static void main(String[] args) {Outer outer = new Outer();outer.method();} }
1.4 匿名内部类
- 定义:匿名内部类是没有名字的内部类,通常用于实现接口或继承类,并且只使用一次。
- 特点:
- 匿名内部类没有构造方法。
- 匿名内部类的名字由系统自动生成。
- 通常用于启动多线程或事件处理。
- 示例:
interface Greeting {void greet(); }public class Main {public static void main(String[] args) {Greeting greeting = new Greeting() {@Overridepublic void greet() {System.out.println("Hello, Anonymous Inner Class!");}};greeting.greet();} }
1.5 静态内部类
- 定义:静态内部类与成员内部类类似,但使用
static
关键字修饰。 - 访问权限:静态内部类不能访问外部类的非静态成员。
- 示例:
class Outer {static class StaticInner {void display() {System.out.println("Static Inner Class");}} }public class Main {public static void main(String[] args) {Outer.StaticInner staticInner = new Outer.StaticInner();staticInner.display();} }
1.6 使用内部类的原因
- 继承独立性:每个内部类可以独立地继承一个接口的实现,无论外部类是否已经继承了某个接口的实现。
- 特性:
- 内部类可以有多个实例,每个实例都有自己的状态信息,并且与其他外围对象的信息相互独立。
- 在单个外部类中,可以让多个内部类以不同的方式实现同一个接口,或者继承同一个类。
- 创建内部类对象的时刻并不依赖于外部类对象的创建。
- 内部类并没有令人迷惑的“is-a”关系,它就是一个独立的实体。
- 内部类提供了更好的封装,除了该外围类,其他类不能访问。
通过使用内部类,可以更好地组织代码,提高代码的可读性和可维护性。
2 Java封装、继承、多态
2.1 引入
Java 面向对象编程的三大特征是封装、继承和多态。这三大特征紧密联系,合理使用这些特征可以大大减少重复代码,提高代码的复用性和可维护性。
2.2 封装
- 概念:封装是指将数据和基于数据的操作封装在一起,形成一个不可分割的独立实体。数据被保护在类的内部,只保留一些对外接口与外部进行交互。
- 好处:
- 减少耦合。
- 类内部的结构可以自由修改。
- 可以对成员进行更精确的控制。
- 隐藏信息,实现细节。
- 示例:
class Person {private String name;private int age;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;} }
2.3 继承
- 概念:继承是面向对象编程中的一个概念,允许子类继承父类的属性和方法,从而复用代码。
- 分类:
- 单继承:一个子类只有一个父类。
- 多继承:Java 不支持多继承,但可以通过实现接口达到类似效果。
- 实现:
- extends 关键字:
class Animal {void sayHello() {System.out.println("Hello from Animal");} }class Dog extends Animal { }public class Main {public static void main(String[] args) {Dog dog = new Dog();dog.sayHello(); // 输出 "Hello from Animal"} }
- implements 关键字:
interface DoA {void sayHello(); }interface DoB {void eat(); }class Cat implements DoA, DoB {@Overridepublic void sayHello() {System.out.println("Hello from Cat");}@Overridepublic void eat() {System.out.println("Cat is eating");} }public class Main {public static void main(String[] args) {Cat cat = new Cat();cat.sayHello(); // 输出 "Hello from Cat"cat.eat(); // 输出 "Cat is eating"} }
- extends 关键字:
- 特点:
-
this 和 super 关键字:
-
this
表示当前对象的引用。this.属性 // 调用成员变量,要区别成员变量和局部变量 this.() // 调用本类的某个方法 this() // 表示调用本类构造方法
-
super
表示父类对象的引用。super.属性 // 表示父类对象中的成员变量 super.方法() // 表示父类对象中定义的方法 super() // 表示调用父类构造方法
-
-
构造方法:
- 父类的构造方法不能被继承
- 子类构造方法必须调用父类构造方法。
- 如果子类构造方法中没有显式调用父类构造方法,系统默认调用父类无参构造方法。
-
方法重写(Override):
- 子类重写父类方法,方法名、参数列表和返回值类型必须相同。
-
方法重载(Overload):
- 方法名相同,参数列表不同。
-
- 修饰符:
- 访问修饰符:子类重写的方法不能降低访问权限。
- 非访问修饰符:
static
:静态变量和方法。final
:最终变量、方法和类。abstract
:抽象类和方法。
2.4 多态
- 概念:多态是指同一个类的对象在不同情况下表现出的不同行为和状态。
- 前提条件:
- 子类继承父类。
- 子类重写父类的方法。
- 父类引用指向子类对象。
- 示例:
class Animal {void makeSound() {System.out.println("Animal sound");} }class Dog extends Animal {@Overridevoid makeSound() {System.out.println("Woof");} }public class Main {public static void main(String[] args) {Animal animal = new Dog();animal.makeSound(); // 输出 "Woof"} }
- 多态与后期绑定:
- 在运行时根据对象的类型进行方法调用。
- 多态与构造方法:
- 在构造方法中调用多态方法时,可能会出现意外结果。
- 多态与向下转型:
- 向下转型可能抛出
ClassCastException
,需要谨慎使用。
- 向下转型可能抛出
2.5 小结
封装:是对类的封装,封装是对类的属性和方法进行封装,只对外暴露方法而不暴露具体使用细节,所以我们一般设计类成员变量时候大多设为私有而通过一些 get、set 方法去读写。
继承:子类继承父类,即“子承父业”,子类拥有父类除私有的所有属性和方法,自己还能在此基础上拓展自己新的属性和方法。主要目的是复用代码。
多态:多态是同一个行为具有多个不同表现形式或形态的能力。即一个父类可能有若干子类,各子类实现父类方法有多种多样,调用父类方法时,父类引用变量指向不同子类实例而执行不同方法,这就是所谓父类方法是多态的
3 思维导图
4 参考链接
- 聊聊Java内部类:成员内部类、局部内部类、匿名内部类、静态内部类
- 深入理解Java三大特性:封装、继承和多态