四,Java面向对象
Java面向对象:封装与构造方法笔记
封装
-
private关键字:
- 概述:
private是Java中的访问修饰符,用于隐藏类的内部细节,只通过公共方法(public)提供访问。 - 特点: 使用
private修饰的成员变量或方法只能在同一个类内部访问,不能被类的外部直接访问。 - 使用方式:
- 成员变量:
this.成员变量名,用于区分成员变量和方法参数同名的情况。 - 构造方法:
this(参数列表),用于在一个构造方法中调用另一个构造方法,实现构造方法的重载。 - 成员方法:
this.成员方法名(参数列表),虽然不常见,但在某些情况下可以用来调用当前对象的其他方法。
- 成员变量:
- 概述:
-
this关键字:
- 概述:
this关键字指向当前对象的引用,可以用来访问当前对象的属性和方法。 - 使用场景:
- 区分成员变量和局部变量(参数)同名时。
- 在构造方法中调用另一个构造方法(构造方法重载)。
- 概述:
-
重载(Overloading):
- 概述: 在同一个类中创建多个同名方法,但参数列表不同(参数类型、个数或顺序不同)。
- 特点: 重载与方法的返回类型无关,仅与参数列表有关。
构造方法
- 概述: 构造方法是一种特殊的方法,用于创建对象时初始化对象的状态。
- 特点:
- 构造方法名必须与类名完全相同。
- 构造方法没有返回类型,连
void都不能有。 - 如果没有显式定义构造方法,Java虚拟机(JVM)会提供一个默认的无参构造方法。
- 可以定义多个构造方法,实现构造方法的重载,以支持不同的初始化方式。
示例代码
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)
-
概述:
- 重写是子类提供父类方法的特定实现的过程,使得子类可以提供特定于子类的行为。
- 子类重写的方法必须与父类中的方法具有相同的返回类型、方法名和参数列表。
-
注意事项:
- 子类无法重写父类中私有的成员。
- 子类无法重写父类中静态的成员。
- 子类重写时,方法访问权限不能比父类中的更严格。例如,如果父类方法是
public,子类重写的方法不能是protected或private。
示例代码
// 父类
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中,多态意味着可以使用父类类型的引用指向子类的对象,并通过这个引用来调用在子类中重写的方法。
-
实现前提:
- 继承关系: 子类必须继承自父类。
- 方法重写: 子类必须重写父类的方法。
- 父类引用指向子类对象: 使用父类类型的引用变量来引用子类的对象。
访问成员的特点
-
成员变量:
- 编译时: 查看引用变量的类型(左边的类型)。
- 运行时: 查看实际对象的类型(左边的类型)。
- 由于成员变量不是多态的一部分,所以运行时总是查看引用变量的类型。
-
成员方法:
- 编译时: 查看引用变量的类型(左边的类型)。
- 运行时: 查看实际对象的类型(右边的类型),即调用实际对象的方法。
- 成员方法是多态的核心,允许在运行时根据对象的实际类型来调用相应的方法。
-
静态成员方法:
- 编译时: 查看引用变量的类型(左边的类型)。
- 运行时: 查看引用变量的类型(左边的类型),因为静态方法不支持多态。
多态的好处
- 提高代码的维护性: 通过继承和多态,可以更容易地修改和扩展程序,因为可以添加新的子类而不需要修改现有代码。
- 提高代码的扩展性: 多态允许程序在不修改现有代码的情况下,通过添加新的子类来扩展功能。
多态形式
-
类多态:
- 通过继承和方法重写实现多态。
- 例如,
Animal类和继承自Animal的Dog类,使用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用于声明一个类或方法为抽象的。 - 修饰的东西: 可以修饰类和方法。
抽象类特征
-
含有抽象方法的类必须是抽象类:
- 如果一个类中包含至少一个抽象方法(没有具体实现的方法),那么这个类必须被声明为抽象类。
- 抽象方法使用
abstract关键字声明,并且没有方法体。
-
抽象类可以包含具体实现的方法:
- 抽象类不仅可以包含抽象方法,还可以包含具体实现的方法(即有方法体的方法)。
-
子类继承抽象类必须重写所有抽象方法:
- 当一个具体的类(非抽象类)继承一个抽象类时,它必须提供所有继承的抽象方法的具体实现。
- 这确保了抽象类的抽象方法在子类中得到适当的实现。
-
抽象类继承抽象类时,可以选择性重写:
- 如果一个抽象类继承自另一个抽象类,它可以重写继承的抽象方法,也可以不重写。
- 抽象类继承抽象类时,可以添加新的抽象方法,也可以不添加。
示例代码
// 抽象类示例
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中用于定义一组方法规范,类通过实现接口来扩展额外的功能。
- 接口支持多继承,类可以实现多个接口。
- 包用于组织类和接口,有助于代码的模块化和管理。
- 权限修饰符控制了类、方法和字段的访问级别。
- 内部类提供了访问外部类成员的额外方式,而匿名内部类适用于一次性使用场景。