java-OOP核心:封装、继承、多态、接口和抽象类、内部类

 1、封装(Encapsulation)

  • 怎么做:属性用private修饰,提供publicgetter/setter

  • 为什么做:保护数据不被随意修改,你可以在setter里加校验逻辑(比如年龄不能为负)

// 父类:Animal
public class Animal {
    // 1. 封装属性:用 private 修饰,外部不能直接访问
    private String name;

    // 2. 提供公共的 getter/setter 来访问属性
    public String getName() {
        return name;
    }

    public void setName(String name) {
        if (name != null && !name.isEmpty()){  //判断name是否为空
            this.name = name;
        } else{
            System.out.println("name不能为空!");
        }
    }
        // 3. 定义一个“发声”的方法(具体怎么叫,由子类去实现)
    public void makeSound() {
        System.out.println("动物发出了某种声音...");
    }
}

 2、继承(Inheritance)

  • 语法class 子类 extends 父类

  • 为什么做:复用代码实现扩展子类的功能。
  • 子类获取的:父类的publicprotected成员,private的成员也被继承、但因不可见而无法直接访问

  • super关键字:访问父类成员、调用父类构造方法(super()必须是第一句)。

    • super.父类成员:访问当前对象的父类的成员。
    • this.成员:访问当前对象的成员。
    • super():调用父类的构造方法(必须写在第一行),默认编译器会自动加一个 super() 调用父类无参构造。
      • 创建子类对象:必须先完成父类对象的初始化(即先调用父类构造方法),再初始化子类自己的部分(再调用子类的构造方法)。
    • this():调用本类的其他构造方法,复用本类的初始化逻辑(this()和super()只能二选一,两个最终都一定会先执行到父类的构造方法)。
  • 方法重写(Override):子类重新定义父类方法。注解@Override 建议写上,可以检查是否写错。

  • 一个关键限制:Java是单继承(一个类只能有一个父类),但可以实现多个接口。

// 子类:Cat 继承 Animal
public class Cat extends Animal {
    // 重写父类的 makeSound 方法
    @Override
    public void makeSound() {
        // 调用父类的 getName() 方法(因为name是private,通过getter访问)
        System.out.println(getName() + " 喵喵叫~~");
    }
}

// 子类:Dog 继承 Animal
public class Dog extends Animal {
    @Override
    public void makeSound() {
        System.out.println(getName() + " 汪汪叫!!");
    }
}

3、多态(Polymorphism)

  • 含义:同一个行为,不同对象表现出不同形态。比如猫叫声是喵,狗叫声是汪。

  • 实现条件:继承 + 重写方法 + 父类引用指向子类对象(Parent p = new Child();)。

    • 父类引用访问重写方法,实际是访问子类重写后的版本
    • 父类引用:不能访问子类特有的成员(子类有、父类没有),通过向下转型才可以访问子类特有的成员
if (animal instanceof Cat) { //判断animal是否是Cat(包括Cat子类)的实例,
    Cat myCat = (Cat) animal; // 向下转型
    myCat.play(); // 现在可以调用Cat特有的play()方法
}
  • 好处:让代码更灵活,比如方法参数写成父类类型,就能接收所有子类对象。

public class TestPolymorphism {
    public static void main(String[] args) {
        // 1. 创建具体的猫和狗对象
        Cat cat = new Cat();
        cat.setName("小花");  // 使用继承自父类的方法
        Dog dog = new Dog();
        dog.setName("旺财");

        // 2. 多态:用父类引用指向子类对象
        Animal animal1 = cat;  // 自动向上转型
        Animal animal2 = dog;

        // 3. 调用同一个方法,但执行的行为完全不同!
        // 实际执行的是子类重写后的版本
        animal1.makeSound();  // 输出:小花 喵喵叫~~
        animal2.makeSound();  // 输出:旺财 汪汪叫!!

        // 4. 多态的妙用:一个方法可以处理所有动物
        makeAnimalSound(cat);  // 传入子类对象
        makeAnimalSound(dog);
    }

    // 这个方法只依赖 Animal 父类,但能接收所有子类
    public static void makeAnimalSound(Animal animal) {
        animal.makeSound();   // 具体执行哪个版本,由传入的对象类型决定
    }
}

4、接口和抽象类

参考:接口和抽象类介绍

5、内部类

  • 内部类是定义在类内部的类,分为四种:成员内部类、静态内部类、局部内部类、匿名内部类;
  • 为什么需要内部类:间接实现多继承(内部类可以继承另一个类)、提供更好的封装、回调处理等。

成员内部类(非静态

可以访问外部类的所有成员(包括私有);

创建时需要外部类实例;

public class Outer {
    private String outerField = "外部类属性";

    // 成员内部类
    class MemberInner {
        void display() {
            System.out.println("访问:" + outerField); // 可以访问私有属性
        }
    }

    public static void main(String[] args) {
        // 创建方式:先创建外部类对象,再通过它创建内部类对象
        Outer outer = new Outer();
        MemberInner inner = outer.new MemberInner();
        inner.display();
    }
}

 

静态内部类

static修饰;只能访问外部类的静态成员;

创建时不需要外部类实例;

public class Outer {
    private static String staticField = "静态外部类属性";
    private String Field = "外部类属性";

    // 静态内部类
    static class StaticInner {
        void display() {
            System.out.println("访问:" + staticField); // 只能访问外部类的静态成员
            System.out.println("访问:" + Field); // 访问非静态成员,会报错
        }
    }

    public static void main(String[] args) {
        // 创建方式:直接 new,不需要外部类实例
        StaticInner inner = new StaticInner();
        inner.display();
    }
}

 

局部内部类

定义在方法内部;

作用域仅限于该方法;可以访问外部类的成员,以及方法的final局部变量

public class Outer {
    private String outerField = "外部类属性";

    void method() {
        String localVar = "有效final局部变量"; // 有效final(从未被重新赋值的局部变量)
        final String localString = "final局部变量" ; //final变量

        // 局部内部类
        class LocalInner {
            void display() {
                System.out.println("访问:" + outerField); // 可以访问外部类成员
                System.out.println("访问:" + localVar);   
// 可以访问方法的final或"有效 final"的变量 System.out.println("访问:" + localString); } } // 只能在方法内部创建和使用 LocalInner inner = new LocalInner(); inner.display(); } public static void main(String[] args) { new Outer().method(); } }

匿名内部类

没有名字,多用于实现接口或继承类;

public class Outer {
    // 传入Runnable对象,调用Runnable对象的run()
    void execute(Runnable task) {
        task.run();
    }

    public static void main(String[] args) {
        Outer outer = new Outer();

        // 匿名内部类:new 接口/类() { ... },new的是接口的实现类
        // 用匿名内部类 实现 Runnable 接口
        outer.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println("匿名内部类执行了");
            }
        });

        // 也可以用来继承抽象类或普通类(写法类似)
        // Thread t = new Thread() { ... };
    }
}

 

posted @ 2026-08-04 11:03  FengweiTech  阅读(6)  评论(0)    收藏  举报