四,Java面向对象

bjynjj / 2024-10-17 / 原文

Java面向对象:封装与构造方法笔记

封装

  • private关键字:

    • 概述: private是Java中的访问修饰符,用于隐藏类的内部细节,只通过公共方法(public)提供访问。
    • 特点: 使用private修饰的成员变量或方法只能在同一个类内部访问,不能被类的外部直接访问。
    • 使用方式:
      • 成员变量: this.成员变量名,用于区分成员变量和方法参数同名的情况。
      • 构造方法: this(参数列表),用于在一个构造方法中调用另一个构造方法,实现构造方法的重载。
      • 成员方法: this.成员方法名(参数列表),虽然不常见,但在某些情况下可以用来调用当前对象的其他方法。
  • this关键字:

    • 概述: this关键字指向当前对象的引用,可以用来访问当前对象的属性和方法。
    • 使用场景:
      • 区分成员变量和局部变量(参数)同名时。
      • 在构造方法中调用另一个构造方法(构造方法重载)。
  • 重载(Overloading):

    • 概述: 在同一个类中创建多个同名方法,但参数列表不同(参数类型、个数或顺序不同)。
    • 特点: 重载与方法的返回类型无关,仅与参数列表有关。

构造方法

  • 概述: 构造方法是一种特殊的方法,用于创建对象时初始化对象的状态。
  • 特点:
    1. 构造方法名必须与类名完全相同。
    2. 构造方法没有返回类型,连void都不能有。
    3. 如果没有显式定义构造方法,Java虚拟机(JVM)会提供一个默认的无参构造方法。
    4. 可以定义多个构造方法,实现构造方法的重载,以支持不同的初始化方式。

示例代码

public class Person {
    private String name; // 私有成员变量
    private int age;

    // 无参构造方法
    public Person() {
    }

    // 带参构造方法
    public Person(String name, int age) {
        this.name = name; // 使用this区分成员变量和参数
        this.age = age;
    }

    // 成员方法
    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    // 重载方法示例
    public void display() {
        System.out.println("Name: " + name + ", Age: " + age);
    }

    public void display(String message) {
        System.out.println(message + " Name: " + name + ", Age: " + age);
    }
}

总结

  • 封装是面向对象编程的核心概念之一,通过private关键字实现对类内部状态的隐藏,通过this关键字访问当前对象的成员。
  • 重载是Java中一种多态的实现方式,允许在同一个类中定义多个同名方法,但参数列表必须不同。
  • 构造方法用于创建对象时初始化对象的状态,可以有多个构造方法(重载),也可以不显式定义,让JVM提供默认构造方法。

Java面向对象编程笔记:继承与final关键字

继承

  • 概述:

    • 继承是面向对象编程中的一个核心概念,它允许创建一个新类(子类)继承另一个类(父类)的属性和方法。
    • 使用extends关键字来实现继承。
  • 特点:

    • 子类继承父类的公共(public)和受保护(protected)成员。
    • 子类无法继承父类中的私有(private)成员和静态(static)成员。
    • 子类无法继承父类的构造方法,但可以通过super()调用父类的构造方法。
  • 构造方法:

    • 子类构造方法的第一行默认包含super(),它调用父类的无参构造方法。
    • 如果父类没有无参构造方法,子类构造方法必须显式地使用super(参数列表)来调用父类的构造方法。
  • 成员访问:

    • 使用super.成员变量名访问父类的成员变量。
    • 使用super.成员方法名(参数列表)调用父类的成员方法。

重写(Overriding)

  • 概述:

    • 重写是子类提供父类方法的特定实现的过程,使得子类可以提供特定于子类的行为。
    • 子类重写的方法必须与父类中的方法具有相同的返回类型、方法名和参数列表。
  • 注意事项:

    1. 子类无法重写父类中私有的成员。
    2. 子类无法重写父类中静态的成员。
    3. 子类重写时,方法访问权限不能比父类中的更严格。例如,如果父类方法是public,子类重写的方法不能是protectedprivate

示例代码

// 父类
class Animal {
    public void eat() {
        System.out.println("Animal is eating.");
    }
}

// 子类
class Dog extends Animal {
    // 重写父类的eat方法
    @Override
    public void eat() {
        System.out.println("Dog is eating dog food.");
    }
    
    // 子类构造方法
    public Dog() {
        super(); // 调用父类的无参构造方法
    }
}

public class TestInheritance {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.eat(); // 输出: Dog is eating dog food.
    }
}

final关键字

  • 概述:

    • final关键字在Java中用于声明类、方法和变量的最终状态,表示“最终的”或“不可变的”。
    • 根据不同的上下文,final可以有不同的含义和用途。
  • final类:

    • 当一个类被声明为final时,这个类不能被继承。
    • 示例:final class FinalClass {}
    • 常用于设计不可扩展的类,如String类。
  • final方法:

    • 当一个方法被声明为final时,这个方法不能被子类重写。
    • 示例:public final void finalMethod() {}
    • 常用于确保方法的行为不被子类改变,增强程序的稳定性和安全性。
  • final变量:

    • 当一个变量被声明为final时,这个变量一旦被赋值后,其值就不能被改变。
    • 对于基本数据类型,这意味着变量的值不可变。
    • 对于对象引用,这意味着引用本身不可变,但对象的内容可以改变。
    • 示例:final int finalNumber = 10;final StringBuilder finalBuilder = new StringBuilder("Initial");
  • final参数:

    • 在方法参数前使用final,表示该参数在方法内部不可被修改。
    • 这种用法较少见,但可以用于确保方法不会修改传入的参数值。

继承总结

  • 继承允许代码复用,子类可以继承父类的属性和方法,但不能继承私有成员和静态成员。
  • 子类构造方法默认调用父类的无参构造方法,如果父类没有无参构造方法,则必须在子类构造方法中显式调用父类的其他构造方法。
  • 重写是子类提供父类方法特定实现的过程,必须保持方法签名一致,且访问权限不能更严格。

final关键字总结

  • final关键字用于声明类、方法和变量的最终状态,确保它们不可被修改或继承。
  • 使用final可以增强程序的稳定性和安全性,防止意外的修改或扩展。
  • final变量一旦赋值后不可变,但对象引用的final仅限制引用本身,对象内容可以改变。

Java面向对象笔记

多态概述

  • 多态的含义:

    • 多态是指允许不同类的对象对同一消息做出响应的能力。
    • 在Java中,多态意味着可以使用父类类型的引用指向子类的对象,并通过这个引用来调用在子类中重写的方法。
  • 实现前提:

    1. 继承关系: 子类必须继承自父类。
    2. 方法重写: 子类必须重写父类的方法。
    3. 父类引用指向子类对象: 使用父类类型的引用变量来引用子类的对象。

访问成员的特点

  • 成员变量:

    • 编译时: 查看引用变量的类型(左边的类型)。
    • 运行时: 查看实际对象的类型(左边的类型)。
    • 由于成员变量不是多态的一部分,所以运行时总是查看引用变量的类型。
  • 成员方法:

    • 编译时: 查看引用变量的类型(左边的类型)。
    • 运行时: 查看实际对象的类型(右边的类型),即调用实际对象的方法。
    • 成员方法是多态的核心,允许在运行时根据对象的实际类型来调用相应的方法。
  • 静态成员方法:

    • 编译时: 查看引用变量的类型(左边的类型)。
    • 运行时: 查看引用变量的类型(左边的类型),因为静态方法不支持多态。

多态的好处

  1. 提高代码的维护性: 通过继承和多态,可以更容易地修改和扩展程序,因为可以添加新的子类而不需要修改现有代码。
  2. 提高代码的扩展性: 多态允许程序在不修改现有代码的情况下,通过添加新的子类来扩展功能。

多态形式

  • 类多态:

    • 通过继承和方法重写实现多态。
    • 例如,Animal类和继承自AnimalDog类,使用Animal类型的引用指向Dog对象。
  • 抽象多态:

    • 通过抽象类和接口实现多态。
    • 抽象类和接口定义了方法的签名,具体的实现由子类提供。
  • 接口多态:

    • 通过接口实现多态。
    • 接口定义了一组方法规范,任何实现了该接口的类都必须提供这些方法的具体实现。

示例代码

// 父类
class Animal {
    public void makeSound() {
        System.out.println("Animal makes a sound");
     }
}

// 子类
class Dog extends Animal {
    @Override
    public void makeSound() {
        System.out.println("Dog barks");
     }
}

public class PolymorphismExample {
    public static void main(String[] args) {
         Animal animal = new Dog(); // 父类引用指向子类对象
         animal.makeSound(); // 输出: Dog barks
     }
}

多态部分总结

  • 多态是面向对象编程的核心概念之一,它允许通过父类类型的引用来操作子类对象。
  • 多态提高了代码的可维护性和扩展性,是实现灵活和可扩展程序设计的关键。
  • 通过继承、方法重写和父类引用指向子类对象,可以实现类多态、抽象多态和接口多态。

Java面向对象抽象类笔记

抽象类定义

  • 关键字: abstract 用于声明一个类或方法为抽象的。
  • 修饰的东西: 可以修饰类和方法。

抽象类特征

  1. 含有抽象方法的类必须是抽象类:

    • 如果一个类中包含至少一个抽象方法(没有具体实现的方法),那么这个类必须被声明为抽象类。
    • 抽象方法使用abstract关键字声明,并且没有方法体。
  2. 抽象类可以包含具体实现的方法:

    • 抽象类不仅可以包含抽象方法,还可以包含具体实现的方法(即有方法体的方法)。
  3. 子类继承抽象类必须重写所有抽象方法:

    • 当一个具体的类(非抽象类)继承一个抽象类时,它必须提供所有继承的抽象方法的具体实现。
    • 这确保了抽象类的抽象方法在子类中得到适当的实现。
  4. 抽象类继承抽象类时,可以选择性重写:

    • 如果一个抽象类继承自另一个抽象类,它可以重写继承的抽象方法,也可以不重写。
    • 抽象类继承抽象类时,可以添加新的抽象方法,也可以不添加。

示例代码

// 抽象类示例
abstract class Animal {
    // 抽象方法
    abstract void makeSound();

    // 具体实现的方法
    void eat() {
        System.out.println("Animal eats food.");
    }
}

// 具体类继承抽象类
class Dog extends Animal {
    // 重写抽象方法
    void makeSound() {
        System.out.println("Dog barks.");
    }
}

public class AbstractClassExample {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.makeSound(); // 输出: Dog barks.
        dog.eat();      // 输出: Animal eats food.
    }
}

抽象类总结

  • 抽象类是不能被实例化的类,它通常用于表示一个抽象概念或模板。
  • 抽象类可以包含抽象方法和具体实现的方法。
  • 抽象类的目的是为子类提供一个共同的接口和部分实现,同时强制子类实现特定的行为。
  • 抽象类的使用提高了代码的复用性和可维护性,是面向对象设计中实现多态和封装的重要工具。

Java面向对象类和接口继承关系及包和内部类笔记

接口

  • 概述:

    • 接口是一种引用类型,它定义了一组方法规范,但不提供方法的具体实现。
    • 接口用于表示一个类中额外扩展的功能。
  • 成员特点:

    • 常量: 接口中的所有字段默认都是public static final,即它们是公开的、静态的、最终的(不可变的)。
    • 抽象方法: 接口中的方法默认都是public abstract,即公开的、抽象的,必须由实现接口的类提供具体实现。
  • 接口继承:

    • 接口之间可以继承,一个接口可以继承多个接口,实现多继承的效果。
  • 类与接口关系:

    • 类可以实现一个或多个接口,通过implements关键字声明。

  • 包的分裂:
    • 按照功能划分: 通常将具有相似功能的类放在同一个包中。
    • 按照角色划分: 根据类在应用程序中的角色或职责进行包的划分。

权限修饰符

  • public: 类、方法和字段可以被任何其他对象访问。
  • protected: 类、方法和字段可以被同一个包内的类以及其他包中的子类访问。
  • 默认(无修饰符): 类、方法和字段可以被同一个包内的所有类访问。
  • private: 类、方法和字段只能被定义它们的类访问。

内部类

  • 成员内部类:

    • 定义在另一个类的内部,可以访问外部类的所有成员,包括私有成员。
  • 局部内部类:

    • 定义在方法或作用域内,只能在定义它们的方法或作用域内访问。
  • 匿名内部类:

    • 没有名称的内部类,通常用于实现接口或继承抽象类的单次使用场景。

接口抽象类实例化

  • Java 8之后,接口可以包含默认方法和静态方法,这些方法可以有具体实现。
  • Java 9引入了私有方法和私有静态方法,允许在接口内部复用代码。

示例代码

// 接口定义
interface Animal {
     void makeSound(); // 抽象方法
}

interface Pet {
     void play(); // 抽象方法
}

// 类实现接口
class Dog implements Animal, Pet {
     public void makeSound() {
         System.out.println("Dog barks");
     }
     
     public void play() {
         System.out.println("Dog plays");
     }
}

// 匿名内部类示例
Animal animal = new Animal() {
     public void makeSound() {
         System.out.println("Anonymous animal makes a sound");
     }
};

// 接口抽象类实例化
interface Greeting {
     default void greet() {
         System.out.println("Hello, World!");
     }
}

class GreetingImpl implements Greeting {
     // 可以选择性地覆盖默认方法
}

public class InterfaceExample {
     public static void main(String[] args) {
         Dog dog = new Dog();
         dog.makeSound();
         dog.play();
         
         animal.greet();
     }
}

总结

  • 接口在Java中用于定义一组方法规范,类通过实现接口来扩展额外的功能。
  • 接口支持多继承,类可以实现多个接口。
  • 包用于组织类和接口,有助于代码的模块化和管理。
  • 权限修饰符控制了类、方法和字段的访问级别。
  • 内部类提供了访问外部类成员的额外方式,而匿名内部类适用于一次性使用场景。