面向对象进阶
继承
基本语法
java
// 父类
public class Animal {
protected String name;
protected int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public void eat() {
System.out.println(name + "正在吃东西");
}
public void sleep() {
System.out.println(name + "正在睡觉");
}
}
// 子类
public class Dog extends Animal {
private String breed;
public Dog(String name, int age, String breed) {
super(name, age); // 调用父类构造方法
this.breed = breed;
}
public void bark() {
System.out.println(name + "正在汪汪叫");
}
}
// 使用
Dog dog = new Dog("旺财", 3, "金毛");
dog.eat(); // 继承自父类
dog.bark(); // 子类特有方法继承特点
- Java单继承(一个类只能有一个直接父类)
- 可以多层继承
- 子类继承父类的非私有成员
- 构造方法不能继承
super关键字
调用父类构造方法
java
public class Cat extends Animal {
private String color;
public Cat(String name, int age, String color) {
super(name, age); // 必须在第一行
this.color = color;
}
}访问父类成员
java
public class Bird extends Animal {
public Bird(String name, int age) {
super(name, age);
}
@Override
public void eat() {
super.eat(); // 调用父类方法
System.out.println(name + "喜欢吃虫子");
}
public void showParent() {
System.out.println(super.name); // 访问父类变量
System.out.println(super.age);
}
}方法重写
重写规则
- 方法名、参数列表必须相同
- 返回类型可以相同或是父类返回类型的子类
- 访问权限不能更严格
- 不能重写private、static、final方法
java
public class Shape {
public double getArea() {
return 0;
}
public void draw() {
System.out.println("绘制图形");
}
}
public class Circle extends Shape {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
public double getArea() {
return Math.PI * radius * radius;
}
@Override
public void draw() {
System.out.println("绘制圆形");
}
}@Override注解
java
@Override // 编译器检查是否正确重写
public double getArea() {
return Math.PI * radius * radius;
}多态
多态概念
同一个方法调用,不同对象有不同的行为。
java
public class PolymorphismDemo {
public static void main(String[] args) {
// 父类引用指向子类对象
Animal animal1 = new Dog("旺财", 3);
Animal animal2 = new Cat("咪咪", 2);
// 同样的方法调用,不同的行为
animal1.eat(); // 旺财正在吃东西
animal2.eat(); // 咪咪正在吃东西
// 类型检查
if (animal1 instanceof Dog) {
Dog dog = (Dog) animal1; // 向下转型
dog.bark();
}
}
}向上转型与向下转型
java
// 向上转型(自动)
Dog dog = new Dog("旺财", 3);
Animal animal = dog; // 向上转型
// 向下转型(需要强制转换)
Animal a = new Dog("旺财", 3);
if (a instanceof Dog) {
Dog d = (Dog) a; // 向下转型
d.bark();
}
// Java 16+ 模式匹配
if (a instanceof Dog d) {
d.bark(); // 直接使用d
}抽象类
定义抽象类
java
// 抽象类
public abstract class Shape {
protected String color;
public Shape(String color) {
this.color = color;
}
// 抽象方法(没有实现)
public abstract double getArea();
public abstract double getPerimeter();
// 具体方法
public void display() {
System.out.println("颜色: " + color);
System.out.println("面积: " + getArea());
System.out.println("周长: " + getPerimeter());
}
}
// 具体子类
public class Rectangle extends Shape {
private double width;
private double height;
public Rectangle(String color, double width, double height) {
super(color);
this.width = width;
this.height = height;
}
@Override
public double getArea() {
return width * height;
}
@Override
public double getPerimeter() {
return 2 * (width + height);
}
}抽象类特点
- 不能实例化
- 可以有抽象方法和具体方法
- 子类必须实现所有抽象方法(除非子类也是抽象类)
- 可以有构造方法
接口
定义接口
java
// 定义接口
public interface Drawable {
void draw(); // 默认public abstract
// 默认方法(Java 8+)
default void printInfo() {
System.out.println("这是一个可绘制的对象");
}
// 静态方法(Java 8+)
static void staticMethod() {
System.out.println("接口静态方法");
}
}
// 实现接口
public class Circle implements Drawable {
@Override
public void draw() {
System.out.println("绘制圆形");
}
}多实现
java
public interface Flyable {
void fly();
}
public interface Swimmable {
void swim();
}
// 实现多个接口
public class Duck implements Flyable, Swimmable {
@Override
public void fly() {
System.out.println("鸭子飞翔");
}
@Override
public void swim() {
System.out.println("鸭子游泳");
}
}接口继承
java
public interface A {
void methodA();
}
public interface B {
void methodB();
}
// 接口多继承
public interface C extends A, B {
void methodC();
}
// 实现类需要实现所有方法
public class Impl implements C {
@Override
public void methodA() { }
@Override
public void methodB() { }
@Override
public void methodC() { }
}内部类
成员内部类
java
public class Outer {
private int outerVar = 10;
// 成员内部类
public class Inner {
private int innerVar = 20;
public void show() {
System.out.println("外部变量: " + outerVar);
System.out.println("内部变量: " + innerVar);
}
}
public void useInner() {
Inner inner = new Inner();
inner.show();
}
}
// 使用
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
inner.show();静态内部类
java
public class Outer {
private static int staticVar = 10;
// 静态内部类
public static class StaticInner {
public void show() {
System.out.println("静态变量: " + staticVar);
}
}
}
// 使用
Outer.StaticInner inner = new Outer.StaticInner();
inner.show();局部内部类
java
public class Outer {
public void method() {
final int localVar = 10;
// 局部内部类
class LocalInner {
public void show() {
System.out.println("局部变量: " + localVar);
}
}
LocalInner inner = new LocalInner();
inner.show();
}
}匿名内部类
java
public interface Greeting {
void greet();
}
public class AnonymousDemo {
public static void main(String[] args) {
// 匿名内部类
Greeting greeting = new Greeting() {
@Override
public void greet() {
System.out.println("Hello!");
}
};
greeting.greet();
// Lambda表达式(Java 8+)
Greeting greeting2 = () -> System.out.println("Hello Lambda!");
greeting2.greet();
}
}抽象类 vs 接口
| 特性 | 抽象类 | 接口 |
|---|---|---|
| 继承 | 单继承 | 多实现 |
| 成员变量 | 可以有各种类型 | 只能是public static final |
| 构造方法 | 可以有 | 不能有 |
| 方法 | 可以有抽象和具体方法 | Java 8前只有抽象方法,之后可以有默认和静态方法 |
| 设计理念 | is-a关系 | has-a能力 |