Java 面向对象高级特性
在掌握了Java基础的面向对象概念之后,我们现在来深入学习一些更高级的特性,这些特性将帮助您编写更加灵活和强大的Java程序。
抽象类与接口
抽象类
抽象类是不能被实例化的类,通常包含一个或多个抽象方法。抽象方法是没有实现的方法,必须在子类中被重写。
java
// 抽象类
abstract class Animal {
protected String name;
protected int age;
// 构造方法
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
// 普通方法
public void sleep() {
System.out.println(name + "正在睡觉");
}
// 抽象方法 - 没有方法体,必须在子类中实现
public abstract void makeSound();
public abstract void move();
// getter方法
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
// 具体子类
class Dog extends Animal {
private String breed;
public Dog(String name, int age, String breed) {
super(name, age);
this.breed = breed;
}
// 实现抽象方法
@Override
public void makeSound() {
System.out.println(name + "汪汪叫");
}
@Override
public void move() {
System.out.println(name + "四脚奔跑");
}
// 子类特有方法
public void wagTail() {
System.out.println(name + "摇尾巴");
}
public String getBreed() {
return breed;
}
}
class Bird extends Animal {
private double wingSpan;
public Bird(String name, int age, double wingSpan) {
super(name, age);
this.wingSpan = wingSpan;
}
// 实现抽象方法
@Override
public void makeSound() {
System.out.println(name + "啾啾叫");
}
@Override
public void move() {
System.out.println(name + "展翅飞翔");
}
// 子类特有方法
public void fly() {
System.out.println(name + "在天空中自由飞翔,翼展" + wingSpan + "米");
}
public double getWingSpan() {
return wingSpan;
}
}
// 抽象类的使用示例
public class AbstractClassExample {
public static void main(String[] args) {
// 不能直接实例化抽象类
// Animal animal = new Animal("动物", 5); // 编译错误
// 可以实例化具体子类
Dog dog = new Dog("旺财", 3, "金毛");
Bird bird = new Bird("小鸟", 1, 0.5);
// 调用方法
dog.makeSound();
dog.move();
dog.wagTail();
dog.sleep();
System.out.println();
bird.makeSound();
bird.move();
bird.fly();
bird.sleep();
// 多态的体现
Animal[] animals = {
new Dog("小白", 2, "哈士奇"),
new Bird("小黄", 1, 0.3)
};
System.out.println("\n=== 多态示例 ===");
for (Animal animal : animals) {
animal.makeSound();
animal.move();
animal.sleep();
System.out.println();
}
}
}接口
接口是一种完全抽象的类,它只包含常量和抽象方法(Java 8之后还可以包含默认方法和静态方法)。
java
// 基础接口
interface Drawable {
// 常量(默认是public static final)
String DEFAULT_COLOR = "黑色";
// 抽象方法(默认是public abstract)
void draw();
// 默认方法(Java 8+)
default void display() {
System.out.println("显示图形");
}
// 静态方法(Java 8+)
static void info() {
System.out.println("这是Drawable接口");
}
// 私有方法(Java 9+)
private void helper() {
System.out.println("辅助方法");
}
// 私有静态方法(Java 9+)
private static void staticHelper() {
System.out.println("静态辅助方法");
}
}
// 另一个接口
interface Resizable {
void resize(double factor);
default void resetSize() {
resize(1.0);
System.out.println("重置大小");
}
}
// 可旋转接口
interface Rotatable {
void rotate(double angle);
default void resetRotation() {
rotate(0);
System.out.println("重置旋转");
}
}
// 实现单个接口
class Circle implements Drawable {
private double radius;
private String color;
public Circle(double radius) {
this.radius = radius;
this.color = DEFAULT_COLOR;
}
@Override
public void draw() {
System.out.println("绘制一个半径为" + radius + "的" + color + "圆形");
}
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
}
// 实现多个接口
class Rectangle implements Drawable, Resizable {
private double width;
private double height;
private String color;
public Rectangle(double width, double height) {
this.width = width;
this.height = height;
this.color = DEFAULT_COLOR;
}
@Override
public void draw() {
System.out.println("绘制一个" + width + "x" + height + "的" + color + "矩形");
}
@Override
public void resize(double factor) {
this.width *= factor;
this.height *= factor;
System.out.println("矩形大小调整为: " + width + "x" + height);
}
public double getWidth() {
return width;
}
public double getHeight() {
return height;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
}
// 实现三个接口
class Image implements Drawable, Resizable, Rotatable {
private String fileName;
private double width;
private double height;
private double rotation;
public Image(String fileName, double width, double height) {
this.fileName = fileName;
this.width = width;
this.height = height;
this.rotation = 0;
}
@Override
public void draw() {
System.out.println("显示图片: " + fileName + " (" + width + "x" + height + ") 旋转" + rotation + "度");
}
@Override
public void resize(double factor) {
this.width *= factor;
this.height *= factor;
System.out.println("图片大小调整为: " + width + "x" + height);
}
@Override
public void rotate(double angle) {
this.rotation = angle;
System.out.println("图片旋转到: " + rotation + "度");
}
public String getFileName() {
return fileName;
}
public double getWidth() {
return width;
}
public double getHeight() {
return height;
}
public double getRotation() {
return rotation;
}
}
// 接口的使用示例
public class InterfaceExample {
public static void main(String[] args) {
// 使用接口引用指向实现类对象
Drawable circle = new Circle(5.0);
Drawable rectangle = new Rectangle(10.0, 8.0);
Drawable image = new Image("photo.jpg", 800, 600);
// 调用接口方法
circle.draw();
rectangle.draw();
image.draw();
System.out.println();
// 调用默认方法
circle.display();
rectangle.display();
image.display();
System.out.println();
// 调用静态方法
Drawable.info();
System.out.println();
// 多态的体现
Drawable[] drawables = {
new Circle(3.0),
new Rectangle(5.0, 4.0),
new Image("screenshot.png", 1920, 1080)
};
System.out.println("=== 绘图示例 ===");
for (Drawable drawable : drawables) {
drawable.draw();
drawable.display();
System.out.println();
}
// 使用Resizable接口
if (rectangle instanceof Resizable) {
Resizable resizable = (Resizable) rectangle;
resizable.resize(1.5);
resizable.resetSize();
}
// 使用Rotatable接口
if (image instanceof Rotatable) {
Rotatable rotatable = (Rotatable) image;
rotatable.rotate(45);
rotatable.resetRotation();
}
}
}抽象类与接口的区别
java
// 抽象类示例
abstract class Vehicle {
protected String brand;
protected String model;
public Vehicle(String brand, String model) {
this.brand = brand;
this.model = model;
}
// 具体方法
public void startEngine() {
System.out.println(brand + " " + model + " 引擎启动");
}
// 抽象方法
public abstract void accelerate();
public abstract void brake();
// getter方法
public String getBrand() { return brand; }
public String getModel() { return model; }
}
// 接口示例
interface Flyable {
void fly();
void land();
}
interface Swimmable {
void swim();
void dive();
}
// 具体实现类 - 继承抽象类并实现接口
class AmphibiousVehicle extends Vehicle implements Swimmable {
public AmphibiousVehicle(String brand, String model) {
super(brand, model);
}
@Override
public void accelerate() {
System.out.println(brand + " " + model + " 在陆地上加速");
}
@Override
public void brake() {
System.out.println(brand + " " + model + " 在陆地上刹车");
}
@Override
public void swim() {
System.out.println(brand + " " + model + " 在水中游泳");
}
@Override
public void dive() {
System.out.println(brand + " " + model + " 潜入水中");
}
}
// 飞行器类 - 实现多个接口
class FlyingCar extends Vehicle implements Flyable {
private int altitude;
public FlyingCar(String brand, String model) {
super(brand, model);
this.altitude = 0;
}
@Override
public void accelerate() {
System.out.println(brand + " " + model + " 在地面加速");
}
@Override
public void brake() {
System.out.println(brand + " " + model + " 在地面刹车");
}
@Override
public void fly() {
this.altitude = 1000;
System.out.println(brand + " " + model + " 飞行在" + altitude + "米高空");
}
@Override
public void land() {
this.altitude = 0;
System.out.println(brand + " " + model + " 安全着陆");
}
public int getAltitude() {
return altitude;
}
}
// 水陆空三栖载具 - 继承抽象类并实现多个接口
class AmphibiousFlyingVehicle extends Vehicle implements Swimmable, Flyable {
private int altitude;
public AmphibiousFlyingVehicle(String brand, String model) {
super(brand, model);
this.altitude = 0;
}
@Override
public void accelerate() {
System.out.println(brand + " " + model + " 在地面加速");
}
@Override
public void brake() {
System.out.println(brand + " " + model + " 在地面刹车");
}
@Override
public void swim() {
System.out.println(brand + " " + model + " 在水中游泳");
}
@Override
public void dive() {
System.out.println(brand + " " + model + " 潜入水中");
}
@Override
public void fly() {
this.altitude = 2000;
System.out.println(brand + " " + model + " 飞行在" + altitude + "米高空");
}
@Override
public void land() {
this.altitude = 0;
System.out.println(brand + " " + model + " 安全着陆");
}
public int getAltitude() {
return altitude;
}
}
// 比较示例
public class AbstractVsInterface {
public static void main(String[] args) {
System.out.println("=== 抽象类与接口比较示例 ===");
// 创建不同类型的载具
AmphibiousVehicle amphibious = new AmphibiousVehicle("Gibbs", "Aquada");
FlyingCar flyingCar = new FlyingCar("Terrafugia", "Transition");
AmphibiousFlyingVehicle hybrid = new AmphibiousFlyingVehicle("Future", "Hybrid");
// 使用Vehicle引用(抽象类)
Vehicle[] vehicles = {amphibious, flyingCar, hybrid};
System.out.println("\n--- 载具基本操作 ---");
for (Vehicle vehicle : vehicles) {
System.out.println("\n载具: " + vehicle.getBrand() + " " + vehicle.getModel());
vehicle.startEngine();
vehicle.accelerate();
vehicle.brake();
}
// 使用Swimmable接口
System.out.println("\n--- 水中操作 ---");
if (amphibious instanceof Swimmable) {
Swimmable swimmer = amphibious;
swimmer.swim();
swimmer.dive();
}
if (hybrid instanceof Swimmable) {
Swimmable swimmer = hybrid;
swimmer.swim();
}
// 使用Flyable接口
System.out.println("\n--- 飞行操作 ---");
if (flyingCar instanceof Flyable) {
Flyable flyer = flyingCar;
flyer.fly();
flyer.land();
}
if (hybrid instanceof Flyable) {
Flyable flyer = hybrid;
flyer.fly();
flyer.land();
}
// 多接口的多态
System.out.println("\n--- 多态示例 ---");
Swimmable[] swimmers = {amphibious, hybrid};
for (Swimmable swimmer : swimmers) {
swimmer.swim();
}
Flyable[] flyers = {flyingCar, hybrid};
for (Flyable flyer : flyers) {
flyer.fly();
}
}
}静态成员与 final 关键字
静态成员
静态成员属于类本身,而不是类的实例。它们在类加载时初始化,所有实例共享同一份静态成员。
java
public class StaticExample {
// 静态变量 - 类变量
private static int instanceCount = 0;
private static final String COMPANY_NAME = "Java技术公司";
// 实例变量
private String name;
private int id;
// 静态代码块 - 类加载时执行
static {
System.out.println("静态代码块执行");
System.out.println("公司名称: " + COMPANY_NAME);
}
// 实例代码块 - 每次创建实例时执行
{
System.out.println("实例代码块执行");
instanceCount++;
this.id = instanceCount;
}
// 构造方法
public StaticExample(String name) {
System.out.println("构造方法执行");
this.name = name;
}
// 静态方法
public static int getInstanceCount() {
return instanceCount;
}
public static String getCompanyName() {
return COMPANY_NAME;
}
// 静态方法不能直接访问实例成员
public static void staticMethod() {
System.out.println("这是静态方法");
System.out.println("公司名称: " + COMPANY_NAME);
// System.out.println(name); // 编译错误 - 不能访问实例变量
// instanceMethod(); // 编译错误 - 不能直接调用实例方法
}
// 实例方法
public void instanceMethod() {
System.out.println("这是实例方法");
System.out.println("姓名: " + name);
System.out.println("ID: " + id);
System.out.println("实例计数: " + instanceCount); // 可以访问静态变量
staticMethod(); // 可以调用静态方法
}
// getter方法
public String getName() {
return name;
}
public int getId() {
return id;
}
// 重写toString方法
@Override
public String toString() {
return "StaticExample{name='" + name + "', id=" + id + "}";
}
public static void main(String[] args) {
System.out.println("=== 静态成员示例 ===");
// 访问静态变量和方法不需要创建实例
System.out.println("初始实例计数: " + StaticExample.getInstanceCount());
System.out.println("公司名称: " + StaticExample.getCompanyName());
// 调用静态方法
StaticExample.staticMethod();
System.out.println("\n--- 创建实例 ---");
// 创建实例
StaticExample obj1 = new StaticExample("对象1");
StaticExample obj2 = new StaticExample("对象2");
StaticExample obj3 = new StaticExample("对象3");
System.out.println("\n--- 实例信息 ---");
System.out.println("obj1: " + obj1);
System.out.println("obj2: " + obj2);
System.out.println("obj3: " + obj3);
System.out.println("\n最终实例计数: " + StaticExample.getInstanceCount());
System.out.println("\n--- 调用实例方法 ---");
obj1.instanceMethod();
System.out.println();
obj2.instanceMethod();
}
}
// 静态导入示例
import static java.lang.Math.*;
import static java.lang.System.*;
class StaticImportExample {
public static void main(String[] args) {
// 使用静态导入后可以直接使用Math和System的静态成员
double result = sqrt(pow(3, 2) + pow(4, 2));
out.println("3² + 4² 的平方根 = " + result);
out.println("π = " + PI);
out.println("随机数 = " + random());
}
}final 关键字
final关键字可以用于变量、方法和类,表示它们是不可改变的。
java
// final类 - 不能被继承
final class Constants {
// final变量 - 常量,只能赋值一次
public static final double PI = 3.141592653589793;
public static final String COMPANY_NAME = "Java技术公司";
public final String VERSION = "1.0.0";
// final方法 - 不能被重写
public final void displayInfo() {
System.out.println("公司: " + COMPANY_NAME);
System.out.println("版本: " + VERSION);
}
}
// 普通类
class MathUtils {
// final实例变量 - 每个实例只能赋值一次
private final double radius;
private final String shapeType;
public MathUtils(double radius, String shapeType) {
this.radius = radius;
this.shapeType = shapeType;
}
// final方法 - 不能被重写
public final double calculateArea() {
switch (shapeType.toLowerCase()) {
case "circle":
return Constants.PI * radius * radius;
case "square":
return radius * radius;
default:
return 0;
}
}
// 非final方法 - 可以被重写
public void displayShapeInfo() {
System.out.println("形状: " + shapeType);
System.out.println("半径/边长: " + radius);
System.out.println("面积: " + calculateArea());
}
// getter方法
public double getRadius() {
return radius;
}
public String getShapeType() {
return shapeType;
}
}
// 继承MathUtils类
class AdvancedMathUtils extends MathUtils {
private final double height;
public AdvancedMathUtils(double radius, String shapeType, double height) {
super(radius, shapeType);
this.height = height;
}
// 重写非final方法
@Override
public void displayShapeInfo() {
super.displayShapeInfo();
System.out.println("高度: " + height);
System.out.println("体积: " + calculateVolume());
}
// 不能重写final方法
// public final double calculateArea() { } // 编译错误
// 计算体积
public double calculateVolume() {
return calculateArea() * height;
}
public double getHeight() {
return height;
}
}
// final类 - 不能被继承
final class UtilityClass {
// 私有构造方法 - 防止实例化
private UtilityClass() {
// 私有构造方法防止外部实例化
}
// 静态工具方法
public static int max(int a, int b) {
return a > b ? a : b;
}
public static int min(int a, int b) {
return a < b ? a : b;
}
public static boolean isEven(int number) {
return number % 2 == 0;
}
public static boolean isOdd(int number) {
return number % 2 != 0;
}
}
// final参数示例
class ParameterExample {
// final参数 - 方法内不能修改参数值
public void processString(final String text) {
System.out.println("处理文本: " + text);
// text = "新值"; // 编译错误 - 不能修改final参数
}
public void processArray(final int[] numbers) {
System.out.println("数组长度: " + numbers.length);
// numbers = new int[5]; // 编译错误 - 不能修改final数组引用
numbers[0] = 100; // 可以修改数组元素 - final只保护引用
System.out.println("修改后第一个元素: " + numbers[0]);
}
}
// final示例
public class FinalExample {
public static void main(String[] args) {
System.out.println("=== final关键字示例 ===");
// 使用final常量
System.out.println("π = " + Constants.PI);
System.out.println("公司名称: " + Constants.COMPANY_NAME);
// 使用final类
Constants constants = new Constants();
constants.displayInfo();
System.out.println("\n--- final变量示例 ---");
// final局部变量
final int MAX_SIZE = 100;
System.out.println("最大尺寸: " + MAX_SIZE);
// MAX_SIZE = 200; // 编译错误 - 不能修改final变量
System.out.println("\n--- final方法示例 ---");
MathUtils circle = new MathUtils(5.0, "circle");
circle.displayShapeInfo();
System.out.println();
AdvancedMathUtils cylinder = new AdvancedMathUtils(3.0, "circle", 10.0);
cylinder.displayShapeInfo();
System.out.println("\n--- final类示例 ---");
System.out.println("最大值: " + UtilityClass.max(10, 20));
System.out.println("最小值: " + UtilityClass.min(10, 20));
System.out.println("10是偶数: " + UtilityClass.isEven(10));
System.out.println("15是奇数: " + UtilityClass.isOdd(15));
System.out.println("\n--- final参数示例 ---");
ParameterExample paramExample = new ParameterExample();
paramExample.processString("Hello World");
int[] array = {1, 2, 3, 4, 5};
System.out.println("修改前数组: " + java.util.Arrays.toString(array));
paramExample.processArray(array);
System.out.println("修改后数组: " + java.util.Arrays.toString(array));
}
}内部类与匿名类
内部类
内部类是定义在另一个类内部的类,它可以访问外部类的所有成员。
java
// 外部类
public class OuterClass {
private String outerField = "外部类字段";
private static String staticOuterField = "静态外部类字段";
// 1. 成员内部类
class InnerClass {
private String innerField = "内部类字段";
public void innerMethod() {
System.out.println("=== 成员内部类方法 ===");
System.out.println("访问内部类字段: " + innerField);
System.out.println("访问外部类字段: " + outerField);
System.out.println("访问静态外部类字段: " + staticOuterField);
// 可以直接访问外部类的所有成员
outerMethod();
staticOuterMethod();
}
public String getInnerField() {
return innerField;
}
}
// 2. 静态内部类
static class StaticInnerClass {
private String staticInnerField = "静态内部类字段";
public void staticInnerMethod() {
System.out.println("=== 静态内部类方法 ===");
System.out.println("访问静态内部类字段: " + staticInnerField);
System.out.println("访问静态外部类字段: " + staticOuterField);
// System.out.println(outerField); // 编译错误 - 不能访问非静态外部类成员
staticOuterMethod();
}
public String getStaticInnerField() {
return staticInnerField;
}
}
// 3. 局部内部类
public void methodWithLocalClass() {
final String localVar = "局部变量";
final int localNumber = 42;
// 局部内部类
class LocalInnerClass {
private String localInnerField = "局部内部类字段";
public void localInnerMethod() {
System.out.println("=== 局部内部类方法 ===");
System.out.println("访问局部内部类字段: " + localInnerField);
System.out.println("访问外部类字段: " + outerField);
System.out.println("访问局部变量: " + localVar);
System.out.println("访问局部数字: " + localNumber);
}
}
// 在方法内创建和使用局部内部类
LocalInnerClass localInner = new LocalInnerClass();
localInner.localInnerMethod();
}
// 外部类方法
public void outerMethod() {
System.out.println("外部类方法被调用");
}
// 静态外部类方法
public static void staticOuterMethod() {
System.out.println("静态外部类方法被调用");
}
// 创建内部类实例的方法
public InnerClass createInnerClass() {
return new InnerClass();
}
// getter方法
public String getOuterField() {
return outerField;
}
}
// 接口定义
interface Drawable {
void draw();
}
interface Clickable {
void click();
}
// 使用内部类的实际示例
class Button {
private String label;
private int x, y, width, height;
public Button(String label, int x, int y, int width, int height) {
this.label = label;
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
// 成员内部类 - 事件处理器
class ButtonHandler implements Drawable, Clickable {
@Override
public void draw() {
System.out.println("绘制按钮: " + label + " 位置(" + x + "," + y + ") 尺寸(" + width + "x" + height + ")");
}
@Override
public void click() {
System.out.println("按钮 '" + label + "' 被点击了!");
}
// 内部类特有方法
public void hover() {
System.out.println("鼠标悬停在按钮 '" + label + "' 上");
}
}
// 获取事件处理器
public ButtonHandler getHandler() {
return new ButtonHandler();
}
// 简化方法
public void draw() {
getHandler().draw();
}
public void click() {
getHandler().click();
}
}
// 内部类示例
public class InnerClassExample {
public static void main(String[] args) {
System.out.println("=== 内部类示例 ===");
// 1. 成员内部类
System.out.println("--- 成员内部类 ---");
OuterClass outer = new OuterClass();
OuterClass.InnerClass inner = outer.createInnerClass();
inner.innerMethod();
// 另一种创建方式
OuterClass.InnerClass inner2 = outer.new InnerClass();
System.out.println("内部类字段: " + inner2.getInnerField());
// 2. 静态内部类
System.out.println("\n--- 静态内部类 ---");
OuterClass.StaticInnerClass staticInner = new OuterClass.StaticInnerClass();
staticInner.staticInnerMethod();
System.out.println("静态内部类字段: " + staticInner.getStaticInnerField());
// 3. 局部内部类
System.out.println("\n--- 局部内部类 ---");
outer.methodWithLocalClass();
// 4. 实际应用示例
System.out.println("\n--- 实际应用示例 ---");
Button button = new Button("提交", 100, 200, 80, 30);
button.draw();
Button.ButtonHandler handler = button.getHandler();
handler.click();
handler.hover();
// 使用接口引用
Drawable drawable = button.getHandler();
drawable.draw();
Clickable clickable = button.getHandler();
clickable.click();
}
}匿名类
匿名类是没有名字的内部类,通常用于创建只需要使用一次的类实例。
java
// 接口定义
interface Greeting {
void sayHello();
}
interface Calculator {
int calculate(int a, int b);
}
// 抽象类
abstract class Animal {
protected String name;
public Animal(String name) {
this.name = name;
}
public abstract void makeSound();
public void sleep() {
System.out.println(name + "正在睡觉");
}
}
// 匿名类示例
public class AnonymousClassExample {
public static void main(String[] args) {
System.out.println("=== 匿名类示例 ===");
// 1. 匿名类实现接口
System.out.println("--- 匿名类实现接口 ---");
Greeting greeting = new Greeting() {
@Override
public void sayHello() {
System.out.println("你好,世界!");
}
};
greeting.sayHello();
// 2. 匿名类实现多个方法的接口
Calculator adder = new Calculator() {
@Override
public int calculate(int a, int b) {
return a + b;
}
};
Calculator multiplier = new Calculator() {
@Override
public int calculate(int a, int b) {
return a * b;
}
};
System.out.println("5 + 3 = " + adder.calculate(5, 3));
System.out.println("5 * 3 = " + multiplier.calculate(5, 3));
// 3. 匿名类继承抽象类
System.out.println("\n--- 匿名类继承抽象类 ---");
Animal dog = new Animal("旺财") {
@Override
public void makeSound() {
System.out.println(name + "汪汪叫");
}
// 可以添加额外方法
public void wagTail() {
System.out.println(name + "摇尾巴");
}
};
dog.makeSound();
dog.sleep();
// dog.wagTail(); // 编译错误 - 父类引用无法访问子类特有方法
// 4. 匿名类继承具体类
System.out.println("\n--- 匿名类继承具体类 ---");
String message = "匿名类示例";
Object obj = new Object() {
// 可以访问外部类的final或effectively final变量
public void displayMessage() {
System.out.println("消息: " + message);
}
@Override
public String toString() {
return "匿名类对象: " + message;
}
};
// 使用反射调用匿名类的特有方法
try {
obj.getClass().getMethod("displayMessage").invoke(obj);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(obj.toString());
// 5. 在方法参数中使用匿名类
System.out.println("\n--- 在方法参数中使用匿名类 ---");
processGreeting(new Greeting() {
@Override
public void sayHello() {
System.out.println("在方法中使用匿名类打招呼");
}
});
// 6. 匿名类与事件处理(模拟)
System.out.println("\n--- 匿名类与事件处理 ---");
simulateButtonEvent();
// 7. 匿名类与多线程
System.out.println("\n--- 匿名类与多线程 ---");
simulateThread();
}
// 处理问候的方法
public static void processGreeting(Greeting greeting) {
System.out.println("处理问候:");
greeting.sayHello();
}
// 模拟按钮事件
public static void simulateButtonEvent() {
// 模拟按钮点击事件处理
EventHandler clickHandler = new EventHandler() {
@Override
public void handle() {
System.out.println("按钮被点击了!");
}
};
EventHandler hoverHandler = new EventHandler() {
@Override
public void handle() {
System.out.println("鼠标悬停在按钮上");
}
};
// 触发事件
clickHandler.handle();
hoverHandler.handle();
}
// 模拟多线程
public static void simulateThread() {
// 使用匿名类创建线程
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 1; i <= 3; i++) {
System.out.println("线程1执行: " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 1; i <= 3; i++) {
System.out.println("线程2执行: " + i);
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
// 启动线程
thread1.start();
thread2.start();
// 等待线程完成
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("所有线程执行完成");
}
}
// 事件处理器接口
interface EventHandler {
void handle();
}
// 实际应用示例:计算器应用
class CalculatorApp {
public static void main(String[] args) {
System.out.println("=== 计算器应用示例 ===");
// 创建不同的计算器操作
Calculator[] operations = {
new Calculator() {
@Override
public int calculate(int a, int b) {
return a + b;
}
},
new Calculator() {
@Override
public int calculate(int a, int b) {
return a - b;
}
},
new Calculator() {
@Override
public int calculate(int a, int b) {
return a * b;
}
},
new Calculator() {
@Override
public int calculate(int a, int b) {
return b != 0 ? a / b : 0;
}
}
};
String[] operationNames = {"加法", "减法", "乘法", "除法"};
int a = 20, b = 4;
System.out.println("计算 " + a + " 和 " + b + " 的结果:");
for (int i = 0; i < operations.length; i++) {
int result = operations[i].calculate(a, b);
System.out.println(operationNames[i] + ": " + result);
}
}
}反射机制
反射机制允许程序在运行时检查和操作类、接口、字段和方法,而不需要在编译时知道它们的名称。
java
import java.lang.reflect.*;
// 示例类用于反射演示
class Person {
private String name;
private int age;
public String email;
// 构造方法
public Person() {
this.name = "未知";
this.age = 0;
this.email = "unknown@example.com";
}
public Person(String name, int age) {
this.name = name;
this.age = age;
this.email = name.toLowerCase().replace(" ", "") + "@example.com";
}
public Person(String name, int age, String email) {
this.name = name;
this.age = age;
this.email = email;
}
// 公共方法
public void introduce() {
System.out.println("大家好,我叫" + name + ",今年" + age + "岁");
}
public void work(String job) {
System.out.println(name + "正在从事" + job + "工作");
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if (age > 0) {
this.age = age;
}
}
// 私有方法
private void secretMethod() {
System.out.println("这是一个私有方法,只有通过反射才能调用");
}
// 静态方法
public static void staticMethod() {
System.out.println("这是一个静态方法");
}
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + ", email='" + email + "'}";
}
}
// 注解用于反射演示
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface MyAnnotation {
String value() default "";
int priority() default 1;
}
// 带注解的类
class AnnotatedClass {
@MyAnnotation(value = "重要方法", priority = 10)
public void importantMethod() {
System.out.println("重要方法被调用");
}
@MyAnnotation(value = "普通方法", priority = 5)
public void normalMethod() {
System.out.println("普通方法被调用");
}
@Deprecated
public void deprecatedMethod() {
System.out.println("过时方法被调用");
}
}
// 反射机制示例
public class ReflectionExample {
public static void main(String[] args) {
System.out.println("=== Java反射机制示例 ===");
try {
// 1. 获取Class对象的三种方式
System.out.println("--- 获取Class对象 ---");
Class<?> class1 = Person.class; // 类字面量
Class<?> class2 = new Person().getClass(); // getClass()方法
Class<?> class3 = Class.forName("Person"); // forName()方法
System.out.println("Class1: " + class1.getName());
System.out.println("Class2: " + class2.getName());
System.out.println("Class3: " + class3.getName());
// 2. 获取类的基本信息
System.out.println("\n--- 类的基本信息 ---");
getClassInfo(class1);
// 3. 获取构造方法
System.out.println("\n--- 构造方法信息 ---");
getConstructors(class1);
// 4. 获取方法
System.out.println("\n--- 方法信息 ---");
getMethods(class1);
// 5. 获取字段
System.out.println("\n--- 字段信息 ---");
getFields(class1);
// 6. 创建对象实例
System.out.println("\n--- 创建对象实例 ---");
createInstance(class1);
// 7. 调用方法
System.out.println("\n--- 调用方法 ---");
invokeMethods(class1);
// 8. 访问私有成员
System.out.println("\n--- 访问私有成员 ---");
accessPrivateMembers(class1);
// 9. 处理注解
System.out.println("\n--- 处理注解 ---");
handleAnnotations();
} catch (Exception e) {
e.printStackTrace();
}
}
// 获取类的基本信息
public static void getClassInfo(Class<?> clazz) {
System.out.println("类名: " + clazz.getSimpleName());
System.out.println("完整类名: " + clazz.getName());
System.out.println("包名: " + clazz.getPackage().getName());
System.out.println("是否为接口: " + clazz.isInterface());
System.out.println("是否为数组: " + clazz.isArray());
System.out.println("父类: " + (clazz.getSuperclass() != null ? clazz.getSuperclass().getName() : "无"));
// 获取实现的接口
Class<?>[] interfaces = clazz.getInterfaces();
if (interfaces.length > 0) {
System.out.println("实现的接口:");
for (Class<?> intf : interfaces) {
System.out.println(" " + intf.getName());
}
}
}
// 获取构造方法信息
public static void getConstructors(Class<?> clazz) throws Exception {
Constructor<?>[] constructors = clazz.getConstructors();
System.out.println("公共构造方法数量: " + constructors.length);
for (Constructor<?> constructor : constructors) {
System.out.println("构造方法: " + constructor.getName());
Class<?>[] parameterTypes = constructor.getParameterTypes();
System.out.print("参数类型: ");
for (int i = 0; i < parameterTypes.length; i++) {
if (i > 0) System.out.print(", ");
System.out.print(parameterTypes[i].getSimpleName());
}
System.out.println();
}
}
// 获取方法信息
public static void getMethods(Class<?> clazz) {
// 获取所有公共方法(包括继承的)
Method[] methods = clazz.getMethods();
System.out.println("公共方法数量: " + methods.length);
// 获取本类声明的所有方法(包括私有方法)
Method[] declaredMethods = clazz.getDeclaredMethods();
System.out.println("本类声明的方法数量: " + declaredMethods.length);
System.out.println("方法列表:");
for (Method method : declaredMethods) {
System.out.print(" " + method.getName() + "(");
Class<?>[] parameterTypes = method.getParameterTypes();
for (int i = 0; i < parameterTypes.length; i++) {
if (i > 0) System.out.print(", ");
System.out.print(parameterTypes[i].getSimpleName());
}
System.out.println(") : " + method.getReturnType().getSimpleName());
System.out.println(" 修饰符: " + Modifier.toString(method.getModifiers()));
}
}
// 获取字段信息
public static void getFields(Class<?> clazz) {
// 获取所有公共字段(包括继承的)
Field[] fields = clazz.getFields();
System.out.println("公共字段数量: " + fields.length);
// 获取本类声明的所有字段(包括私有字段)
Field[] declaredFields = clazz.getDeclaredFields();
System.out.println("本类声明的字段数量: " + declaredFields.length);
System.out.println("字段列表:");
for (Field field : declaredFields) {
System.out.println(" " + field.getName() + " : " + field.getType().getSimpleName());
System.out.println(" 修饰符: " + Modifier.toString(field.getModifiers()));
}
}
// 创建对象实例
public static void createInstance(Class<?> clazz) throws Exception {
// 使用默认构造方法创建实例
Object obj1 = clazz.newInstance();
System.out.println("使用默认构造方法创建: " + obj1);
// 使用指定构造方法创建实例
Constructor<?> constructor = clazz.getConstructor(String.class, int.class);
Object obj2 = constructor.newInstance("张三", 25);
System.out.println("使用指定构造方法创建: " + obj2);
// 使用带参数的构造方法创建实例
Constructor<?> constructor2 = clazz.getConstructor(String.class, int.class, String.class);
Object obj3 = constructor2.newInstance("李四", 30, "lisi@example.com");
System.out.println("使用带参数的构造方法创建: " + obj3);
}
// 调用方法
public static void invokeMethods(Class<?> clazz) throws Exception {
// 创建实例
Constructor<?> constructor = clazz.getConstructor(String.class, int.class);
Object obj = constructor.newInstance("王五", 28);
// 调用无参方法
Method introduceMethod = clazz.getMethod("introduce");
introduceMethod.invoke(obj);
// 调用带参方法
Method workMethod = clazz.getMethod("work", String.class);
workMethod.invoke(obj, "软件开发");
// 调用getter方法
Method getNameMethod = clazz.getMethod("getName");
String name = (String) getNameMethod.invoke(obj);
System.out.println("获取到的名字: " + name);
// 调用setter方法
Method setAgeMethod = clazz.getMethod("setAge", int.class);
setAgeMethod.invoke(obj, 29);
Method getAgeMethod = clazz.getMethod("getAge");
int age = (Integer) getAgeMethod.invoke(obj);
System.out.println("设置后的年龄: " + age);
// 调用静态方法
Method staticMethod = clazz.getMethod("staticMethod");
staticMethod.invoke(null); // 静态方法传入null作为对象
}
// 访问私有成员
public static void accessPrivateMembers(Class<?> clazz) throws Exception {
// 创建实例
Object obj = clazz.newInstance();
// 访问私有字段
Field nameField = clazz.getDeclaredField("name");
nameField.setAccessible(true); // 设置可访问
nameField.set(obj, "通过反射修改的名字");
String name = (String) nameField.get(obj);
System.out.println("通过反射访问私有字段: " + name);
// 调用私有方法
Method secretMethod = clazz.getDeclaredMethod("secretMethod");
secretMethod.setAccessible(true); // 设置可访问
secretMethod.invoke(obj);
}
// 处理注解
public static void handleAnnotations() throws Exception {
Class<?> clazz = AnnotatedClass.class;
// 获取类的方法
Method[] methods = clazz.getDeclaredMethods();
System.out.println("带注解的方法:");
for (Method method : methods) {
// 检查是否有自定义注解
if (method.isAnnotationPresent(MyAnnotation.class)) {
MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
System.out.println("方法: " + method.getName());
System.out.println(" 值: " + annotation.value());
System.out.println(" 优先级: " + annotation.priority());
}
// 检查是否有@Deprecated注解
if (method.isAnnotationPresent(Deprecated.class)) {
System.out.println("方法 " + method.getName() + " 已过时");
}
}
// 调用带注解的方法
AnnotatedClass annotatedObj = new AnnotatedClass();
Method importantMethod = clazz.getMethod("importantMethod");
Method normalMethod = clazz.getMethod("normalMethod");
// 根据注解优先级排序调用
if (importantMethod.isAnnotationPresent(MyAnnotation.class) &&
normalMethod.isAnnotationPresent(MyAnnotation.class)) {
MyAnnotation importantAnnotation = importantMethod.getAnnotation(MyAnnotation.class);
MyAnnotation normalAnnotation = normalMethod.getAnnotation(MyAnnotation.class);
if (importantAnnotation.priority() > normalAnnotation.priority()) {
System.out.println("优先调用重要方法:");
importantMethod.invoke(annotatedObj);
normalMethod.invoke(annotatedObj);
} else {
System.out.println("优先调用普通方法:");
normalMethod.invoke(annotatedObj);
importantMethod.invoke(annotatedObj);
}
}
}
}
// 反射的实际应用:通用对象复制工具
class ReflectionUtils {
// 使用反射复制对象属性
public static <T> T copyObject(T source, Class<T> targetClass) throws Exception {
// 创建目标对象实例
T target = targetClass.newInstance();
// 获取源对象和目标对象的类
Class<?> sourceClass = source.getClass();
// 获取所有声明的字段
Field[] fields = sourceClass.getDeclaredFields();
for (Field field : fields) {
// 设置字段可访问
field.setAccessible(true);
// 获取字段值
Object value = field.get(source);
try {
// 在目标类中查找同名字段
Field targetField = targetClass.getDeclaredField(field.getName());
targetField.setAccessible(true);
targetField.set(target, value);
} catch (NoSuchFieldException e) {
// 如果目标类中没有该字段,忽略
System.out.println("目标类中没有字段: " + field.getName());
}
}
return target;
}
// 使用反射打印对象信息
public static void printObjectInfo(Object obj) throws Exception {
if (obj == null) {
System.out.println("对象为null");
return;
}
Class<?> clazz = obj.getClass();
System.out.println("对象类型: " + clazz.getSimpleName());
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
Object value = field.get(obj);
System.out.println(" " + field.getName() + " = " + value);
}
}
}
// 反射工具使用示例
class ReflectionUtilsExample {
public static void main(String[] args) {
try {
System.out.println("=== 反射工具使用示例 ===");
// 创建原始对象
Person original = new Person("赵六", 35, "zhaoliu@example.com");
System.out.println("原始对象:");
ReflectionUtils.printObjectInfo(original);
// 使用反射复制对象
Person copy = ReflectionUtils.copyObject(original, Person.class);
System.out.println("\n复制对象:");
ReflectionUtils.printObjectInfo(copy);
// 修改复制对象
copy.setAge(40);
System.out.println("\n修改复制对象后:");
System.out.println("原始对象年龄: " + original.getAge());
System.out.println("复制对象年龄: " + copy.getAge());
} catch (Exception e) {
e.printStackTrace();
}
}
}通过本章节的学习,您已经掌握了Java面向对象编程的高级特性,包括抽象类与接口的使用、静态成员与final关键字的应用、内部类与匿名类的创建,以及反射机制的原理和应用。这些特性是Java编程中非常重要的概念,掌握它们将帮助您编写更加灵活、可维护和功能强大的Java程序。