文章目录
- 一、访问权限控制
- 1. 目的
- 2. 访问权限修饰符:
- 3.私有构造器
- 二、复用类
- 1. 组合(Composition):
- 2. 继承(Inheritance):
- 3. 基类的初始化:
- 4. 在组合与继承之间选择:
- 使用组合的情况:
- 使用继承的情况:
- 5. final关键字
- 1. final 修饰类:
- 2. final 修饰方法:
- 3. final 修饰变量(字段):
- 三、多态
- 1. 多态的基本概念:
- 2. 向上转型和向下转型:
- 3. 运行时多态性:
- 4. 抽象类和接口的多态性:
- 5. 多态的应用场景:
- 6. 注意事项和限制:
- 7. 建议:
Java编程思想6~8章
一、访问权限控制
1. 目的
- 封装: 通过将内部实现细节隐藏起来,只向外部提供必要的接口,提高代码的模块化和可维护性。
- 安全性: 限制对某些敏感信息和操作的访问,提高程序的安全性。
- 组织结构: 通过规范访问权限,帮助组织程序结构,降低耦合度。
2. 访问权限修饰符:
- public: 公共的,对所有类可见。被声明为 public 的类、方法、变量可以被任何其他类访问。
- protected: 受保护的,对同一包内的类和所有子类可见。被声明为 protected 的成员可以被同一包内的类和所有子类访问。
- default(包私有): 如果没有使用上述任何关键字,默认为包私有。在同一包内可见,但对其他包的类不可见。
- private: 私有的,仅对本类可见。被声明为 private 的成员只能被所在类的方法访问。
3.私有构造器
当我们写了一个工具类以后,我们可以给它编写一个私有构造器,这样可以防止别人创建它的实例再使用,减少重复创建实例的时间和空间,只需要通过类名.方法名调用即可。
二、复用类
1. 组合(Composition):
组合是通过将一个类的对象嵌入到另一个类中来实现复用。这种方式允许一个类使用另一个类的功能,但不会继承其实现。
class Engine {// 引擎的实现
}class Car {private Engine engine;public Car(Engine engine) {this.engine = engine;}public void start() {engine.start();}
}
2. 继承(Inheritance):
继承是通过创建一个新类,使用已有类的属性和方法,然后在新类中添加或修改功能来实现复用。
class Animal {public void eat() {// 动物吃东西的行为}
}class Dog extends Animal {public void bark() {// 狗叫的行为}
}
3. 基类的初始化:
在继承中,基类的初始化是通过调用基类的构造方法来实现的。子类在创建实例时,需要首先初始化基类的状态,然后再添加自己的额外状态。
在Java中,使用 super() 调用基类的构造方法,这必须是子类构造方法的第一条语句。如果子类的构造方法没有显式调用 super(),则默认会调用基类的无参构造方法。如果基类没有提供无参构造方法,并且子类没有显式调用基类的其他构造方法,那么编译器将报错。
class Animal {private String name;public Animal(String name) {this.name = name;System.out.println("Animal constructor");}public void eat() {System.out.println(name + " is eating");}
}class Dog extends Animal {private String breed;public Dog(String name, String breed) {super(name); // 调用基类构造方法this.breed = breed;System.out.println("Dog constructor");}public void bark() {System.out.println(breed + " dog is barking");}
}public class Main {public static void main(String[] args) {Dog myDog = new Dog("Buddy", "Golden Retriever");myDog.eat(); // 调用基类方法myDog.bark(); // 调用子类方法}
}
在上述例子中,Dog 类继承自 Animal 类。在 Dog 的构造方法中,通过 super(name) 调用了基类 Animal 的构造方法。这样,当创建 Dog 的实例时,首先会执行 Animal 的构造方法,然后再执行 Dog 的构造方法。
4. 在组合与继承之间选择:
使用组合的情况:
松散的耦合(Loose Coupling):
当对象之间的关系需要在运行时动态确定,或者需要更灵活的对象替换时,组合是一个较好的选择。对象之间通过接口进行通信,而不是通过继承关系。
动态配置对象行为:
当需要在运行时动态配置或更改对象的行为时,组合可以提供更灵活的方式。通过替换或添加组件,可以修改对象的行为。
代码复用:
当想要实现代码复用而不引入继承的复杂性时,组合是一种更灵活的选择。可以通过组合来构建包含所需功能的对象,而不必考虑继承层次结构。
接口和多态性需求:
当希望通过接口实现多态性,使得对象能够以相似的方式被使用时,组合通常是更好的选择。通过接口定义,对象可以替换为具有相同接口的其他对象。
使用继承的情况:
是一个关系(Is-a Relationship):
当子类对象是父类对象的一种类型时,适合使用继承。例如,狗是动物的一种类型。
共享基本行为:
当多个类具有共享的基本行为,并且这些行为在整个继承层次结构中都是一致的时,使用继承可以减少代码的重复。
抽象基类:
当希望创建一个通用的抽象基类,而具体的实现由子类提供时,可以使用继承。这对于框架和库的设计很常见。
扩展已有类:
当需要扩展已有类的功能,并且新类可以被视为原始类的扩展时,继承是一种自然的选择。这符合“是一个”关系。
5. final关键字
final 是一个关键字,它可以用于修饰类、方法和变量。final 的主要作用是表示不可改变的、不可继承的、或者不可覆盖的。
1. final 修饰类:
当一个类被声明为 final 时,它表示这个类不能被其他类继承。这通常用于防止对类的进一步修改和扩展。
2. final 修饰方法:
当一个方法被声明为 final 时,它表示这个方法不能被子类覆盖(即不能被重写)。
3. final 修饰变量(字段):
当一个变量(字段)被声明为 final 时,它表示这个变量的值只能被赋值一次,之后不能再修改(成员变量只能在定义时或者构造器中赋值)。对于基本数据类型,这意味着其数值不可改变;对于引用类型,这意味着引用不可变,但对象本身的状态可能是可变的。
class Example {// final 常量,只能被赋值一次final int CONSTANT_VALUE = 10;// final 引用,引用不可变,但对象本身的状态可能是可变的final StringBuilder stringBuilder = new StringBuilder("Hello");void modifyValues() {// 编译错误,不能修改 final 常量的值// CONSTANT_VALUE = 20;// 可以修改 final 引用所指向的对象的状态stringBuilder.append(", World!");}
}
三、多态
1. 多态的基本概念:
-
多态(Polymorphism): 多态是面向对象编程的一个核心概念,它允许不同的子类对象被视为相同的父类对象。
-
方法重写(Method Overriding): 子类可以提供与父类中相同签名的方法,并重新定义其实现。
2. 向上转型和向下转型:
-
向上转型(Upcasting): 将子类对象赋给父类引用。例如:Animal myDog = new Dog();
-
向下转型(Downcasting): 将父类引用转换为子类引用。需要使用强制类型转换,但要注意转型的安全性。
3. 运行时多态性:
-
动态绑定(Dynamic Binding): 在运行时确定对象的类型,并调用相应的方法。
-
运行时类型信息(RTTI): 使用 instanceof 操作符检查对象的实际类型。
4. 抽象类和接口的多态性:
-
抽象类(Abstract Class): 抽象类可以包含抽象方法,子类必须提供实现。可以使用多态性创建指向子类对象的引用。
-
接口(Interface): 接口定义规范,实现类提供具体实现。通过接口可以实现多态性。
5. 多态的应用场景:
-
灵活性和可扩展性: 多态性提高了代码的灵活性,使得程序更容易适应变化和扩展。
-
代码复用: 通过多态性,可以将同一接口的不同实现交替使用,实现代码的复用。
6. 注意事项和限制:
-
方法私有化: 私有方法不会被继承,因此不具备多态性。
-
静态方法和字段: 静态方法和字段属于类,而不是实例,因此不具备多态性。
-
构造器和多态: 构造器不具备多态性,因为在对象构造之前,它的类型已经确定。
7. 建议:
-
遵循多态的原则: 利用多态性设计灵活且易于扩展的代码。
-
理解继承层次结构: 多态性依赖于继承关系,理解类的层次结构对正确使用多态性非常重要。
-
RTTI 的谨慎使用: 使用 instanceof 操作符时需小心,过度使用可能暗示设计上的问题。