封装
封装是指将数据的内部表示隐藏在对象内部,仅通过明确定义的接口与外部世界交互。它的目的是:
- 保护对象内部状态,防止意外修改。
- 允许内部状态在不影响客户端代码的情况下发生变化。
- 促进代码的模块化和可维护性。
Java中的封装通过以下方式实现:
- 私有字段:对象内部状态以私有字段的形式声明,只能在类内部访问。
- 公共/受保护方法:用于与外部世界交互的方法被声明为公共或受保护,允许访问对象内部状态。
继承
继承允许一个类从另一个已存在的类(称为超类)继承属性和方法。它的目的是:
- 代码复用:允许子类共享超类的代码,减少冗余。
- 多态性:允许将子类的对象视为超类的对象,提供更大的灵活性。
- 层次结构:允许创建对象层次结构,其中每个级别具有特定的特性。
Java中的继承通过以下方式实现:
- extends关键字:用于指定子类从哪个超类继承。
- 方法覆盖:子类可以覆盖超类的方法,提供自己的实现。
- final关键字:可以用于防止类或方法被继承或覆盖。
协作
封装和继承在Java对象模型中携手合作,提供了一个强大而灵活的机制来创建和管理对象。
- 封装提供数据安全性:通过封装对象的内部状态,继承可以确保子类不会意外修改超类的数据,维护数据的完整性。
- 继承实现代码复用:通过继承,子类可以访问超类的字段和方法,从而减少重复代码的编写,提高代码的维护性。
- 多态性提供灵活性:多态性允许子类的对象作为超类的对象使用,为应用程序提供了更大的灵活性,使其能够处理不同类型的对象而无需显式转换。
示例
考虑以下Java代码示例,展示封装和继承的协作:
class Shape {
private double area; // 封装内部状态
public double getArea() { // 公共方法提供访问
return area;
}
}
class Square extends Shape {
private double sideLength;
public Square(double sideLength) {
this.sideLength = sideLength;
area = sideLength * sideLength; // 初始化面积
}
@Override
public double getArea() { // 覆盖方法提供子类实现
return area;
}
}
在这个示例中,Shape
类封装了area
字段,而Square
类继承了Shape
并覆盖了getArea()
方法。当创建一个Square
对象时,它从Shape
继承了area
字段,并根据特定形状(正方形)初始化该字段。封装确保了Shape
类的area
字段只能通过公共getArea()
方法访问,而继承允许Square
类重用Shape
类的getArea()
方法并提供其自己的实现。