【Java基础】(二)面向对象

一、类与对象

    • 定义:类是一个模板蓝图,它描述了一类对象共同具有的状态(属性)和行为(方法)。
    • 组成:类主要由以下部分组成:
      • 成员变量:描述对象的属性或状态(例如:String name; int age;)。
      • 成员方法:描述对象的行为或功能(例如:eat(), sleep())。
      • 构造方法:用于在创建对象时初始化对象。
  • 对象
    • 定义:对象是类的一个具体实例。类是抽象的,对象是具体的。
    • 关系“万物皆对象”。你可以把“类”理解为“汽车设计图”,而“对象”就是根据这张设计图生产出来的一辆辆具体的汽车(比如你的车、我的车)。

示例代码:

// 1. 定义一个“类”
public class Student {
    // 成员变量(状态/属性)
    String name;
    int age;

    // 构造方法(用于创建对象)
    public Student(String studentName, int studentAge) {
        this.name = studentName;
        this.age = studentAge;
    }

    // 成员方法(行为)
    public void introduce() {
        System.out.println("大家好,我叫" + name + ",今年" + age + "岁。");
    }
}

// 2. 创建并使用“对象”
public class Main {
    public static void main(String[] args) {
        // 使用 'new' 关键字和构造方法创建对象
        Student student1 = new Student("张三", 20); // student1 是一个对象
        Student student2 = new Student("李四", 19); // student2 是另一个对象

        // 调用对象的方法
        student1.introduce(); // 输出:大家好,我叫张三,今年20岁。
        student2.introduce(); // 输出:大家好,我叫李四,今年19岁。
    }
}

二、封装

封装是面向对象的三大特性之一,其核心思想是“隐藏对象的内部细节,仅对外提供公共的访问方式”

  • 目的

    1. 提高安全性:防止类的代码和数据被随意访问和修改。
    2. 易于维护:内部实现细节的改变,只要对外接口不变,就不会影响其他代码。
  • 实现方式

    1. 使用 private 访问修饰符:将成员变量私有化,使其不能在类的外部直接访问。
    2. 提供公共的 gettersetter 方法:通过这些公共方法来读写私有变量,可以在方法中加入逻辑控制(例如,在setAge方法中检查年龄是否合法)。

示例代码:

public class Student {
    // 使用 private 实现封装
    private String name;
    private int age;

    // 公共的 getter 方法,用于获取属性值
    public String getName() {
        return name;
    }

    // 公共的 setter 方法,用于设置属性值,并可加入逻辑验证
    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        // 在setter中加入控制逻辑
        if (age > 0 && age < 150) {
            this.age = age;
        } else {
            System.out.println("年龄不合法!");
        }
    }
}

public class Main {
    public static void main(String[] args) {
        Student s = new Student();
        // s.name = "张三"; // 错误!name 是 private 的,不能直接访问
        s.setName("张三"); // 正确!通过公共方法访问
        s.setAge(200); // 输出:年龄不合法! (因为200不在0-150之间)
        s.setAge(20);  // 正确设置

        System.out.println(s.getName() + ": " + s.getAge() + "岁");
    }
}

三、继承

继承允许我们基于一个已存在的类来定义一个新类。新类拥有父类的属性和方法,并可以扩展自己的属性和方法。

  • 目的

    1. 代码复用:子类可以直接使用父类的功能,无需重写。
    2. 建立类之间的“is-a”关系(例如:Dog is an Animal)。
  • 关键字extends

  • 特点

    • Java是单继承,一个类只能直接继承一个父类。
    • 子类可以重写父类的方法,以实现自身特定的行为。
    • 子类不能继承父类的构造方法和被声明为 private 的成员。

示例代码:

// 父类
public class Animal {
    String name;

    public void eat() {
        System.out.println(name + "正在吃东西。");
    }
}

// 子类继承父类
public class Dog extends Animal { // Dog 继承自 Animal
    // 子类可以拥有自己的方法
    public void bark() {
        System.out.println(name + "汪汪叫!"); // name 是从父类继承的
    }

    // 重写父类的方法
    @Override
    public void eat() {
        System.out.println(name + "正在啃骨头!"); // 狗吃东西的方式不同
    }
}

public class Main {
    public static void main(String[] args) {
        Dog myDog = new Dog();
        myDog.name = "旺财"; // 继承自父类的属性
        myDog.eat();   // 调用的是子类重写后的方法:输出“旺财正在啃骨头!”
        myDog.bark();  // 调用子类自己的方法:输出“旺财汪汪叫!”
    }
}

四、多态

多态是指同一个行为具有多个不同表现形式或形态的能力。简单说就是“父类引用指向子类对象”,调用相同的方法,会根据实际对象的类型产生不同的行为。

  • 实现条件

    1. 继承
    2. 方法重写
    3. 父类引用指向子类对象:Parent p = new Child();
  • 好处:提高了程序的扩展性可维护性

示例代码:

// 父类
public class Animal {
    public void makeSound() {
        System.out.println("动物发出声音。");
    }
}

// 子类1
public class Cat extends Animal {
    @Override
    public void makeSound() {
        System.out.println("喵喵喵!");
    }
}

// 子类2
public class Duck extends Animal {
    @Override
    public void makeSound() {
        System.out.println("嘎嘎嘎!");
    }
}

public class Main {
    public static void main(String[] args) {
        // 多态的典型体现:父类引用指向子类对象
        Animal animal1 = new Cat();
        Animal animal2 = new Duck();

        // 同一个方法调用,实际执行的是子类重写后的方法
        animal1.makeSound(); // 输出“喵喵喵!”
        animal2.makeSound(); // 输出“嘎嘎嘎!”

        // 这种特性使得代码非常灵活
        Animal[] animals = {new Cat(), new Duck()};
        for (Animal a : animals) {
            a.makeSound(); // 无需判断具体类型,程序会自动调用正确的方法
        }
    }
}

五、抽象类与接口

抽象类

  • 定义:使用 abstract 关键字修饰的类。
  • 特点
    1. 不能实例化:不能直接创建 new AbstractClass() 的对象。
    2. 可以包含抽象方法:使用 abstract 修饰,只有声明没有实现的方法(没有方法体{})。子类必须重写所有的抽象方法,除非子类也是抽象类。
    3. 也可以包含普通方法和成员变量
  • 目的:为一个继承体系提供一个通用的模板,强制子类实现特定的行为。

示例代码:

// 抽象类
public abstract class Shape {
    // 抽象方法
    public abstract double calculateArea();

    // 普通方法
    public void printInfo() {
        System.out.println("我是一个形状。");
    }
}

// 子类必须实现抽象方法
public class Circle extends Shape {
    double radius;

    @Override
    public double calculateArea() {
        return Math.PI * radius * radius;
    }
}

接口

  • 定义:使用 interface 关键字定义。在Java 8之前,它完全是抽象方法的集合。现在它可以包含默认方法静态方法私有方法
  • 特点
    1. 所有方法默认都是 public abstract(在Java 8之前)。
    2. 所有变量默认都是 public static final(常量)。
    3. 一个类可以实现多个接口implements),解决了Java单继承的限制。
  • 目的:定义一套行为规范,强调“能做什么”,而不关心“如何做”。

示例代码:

// 接口
public interface Flyable {
    // 抽象方法(默认就是 public abstract)
    void fly();

    // Java 8 的默认方法
    default void repair() {
        System.out.println("修理飞行装置...");
    }
}

public interface Swimmable {
    void swim();
}

// 类可以实现多个接口
public class Duck extends Animal implements Flyable, Swimmable {
    @Override
    public void fly() {
        System.out.println("鸭子扑棱着翅膀飞。");
    }

    @Override
    public void swim() {
        System.out.println("鸭子在水里游。");
    }
}

抽象类 vs 接口

特性 抽象类 接口
定义关键字 abstract class interface
方法 可包含抽象方法和具体方法 Java 8前全是抽象方法;之后可含默认、静态方法
变量 无特殊限制 默认是 public static final 常量
继承 单继承(一个类只能继承一个抽象类) 多实现(一个类可实现多个接口)
设计目的 “是什么” (is-a),代码复用,模板设计 “能做什么” (has-a/can-do),定义行为规范
构造方法

posted @ 2025-12-09 13:07  berlin-fly  阅读(5)  评论(0)    收藏  举报