Java面向对象四大核心:封装、继承、多态与抽象详解
深入理解Java面向对象编程的四大支柱,掌握如何通过封装保护数据、利用继承复用代码、基于多态实现灵活扩展,以及运用抽象类规范设计模式。
类和对象的基础概念
在Java中,创建类的对象即是对类进行实例化(instance)。面向对象思想的落地主要通过以下三个步骤实现:
- 定义类:设计类的成员变量和成员方法。
- 实例化对象:使用
new关键字创建类的实例。 - 访问结构:通过“对象.属性”或“对象.方法”来操作对象。
每个非静态(non-static)属性的副本独立存在于各自的对象中。修改一个对象的属性不会影响另一个同名属性的值,这体现了对象之间数据的独立性。
子类对象实例化的全过程
理解继承中的实例化过程是掌握面向对象的关键,主要体现在结果和过程两个维度:
- 从结果看(继承性):子类继承父类后,获取了父类声明的所有属性和方法。创建子类对象时,内存中会加载并包含所有父类中声明的属性结构。
- 从过程看(初始化顺序):通过子类构造器创建对象时,必然直接或间接调用父类构造器,直至
java.lang.Object类中空参构造器为止。这意味着在创建子类对象之前,已加载过所有父类结构,因此可以调用相关资源。
注意:虽然调用了父类构造器,但自始至终只创建了一个对象,即为new出来的子类对象。
匿名对象的使用
匿名对象是指没有显式赋给变量名的对象,其特征和使用场景如下:
- 特征:只能使用一次,一旦方法执行完毕,该对象将成为垃圾回收器的待回收对象。
- 使用场景:通常用于方法的参数传递或仅需一次调用的情况。
class Phone {
public void sendEmail() {
System.out.println("发送邮件");
}
}
public class TestAnonymous {
public static void main(String[] args) {
// 普通对象
Phone p = new Phone();
p.sendEmail();
// 匿名对象直接调用方法
new Phone().sendEmail();
// 作为参数传递给其他对象的方法
new PhoneMall().show(new Phone());
}
}
class PhoneMall {
public void show(Phone phone) {
phone.sendEmail();
}
}
1. 封装性 (Encapsulation)
封装的核心在于隐藏对象的属性和实现细节,仅对外提供公共访问方式。其典型体现是将属性私有化(private),并通过公共方法(getXxx / setXxx)进行操作。
权限修饰符的应用
Java提供了四种权限修饰符,它们决定了代码的可访问范围:
- private:当前类可见。
- (缺省/Default):当前包内可见。
- protected:当前包内可见 + 不同包的子类可见。
- public:所有地方可见。
修饰规则:
- 修饰类的内部结构(属性、方法、构造器、内部类)时,可使用任意四种。
- 修饰外部类时,只能使用
缺省或public。若使用public,该类可在任何位置被访问;若为缺省,则仅限同包访问。
2. 继承性 (Inheritance)
继承允许子类重用父类的属性和方法,格式为:class SubClass extends SuperClass {}。
继承的核心特点
- 单继承性:一个类只能有一个直接父类,但一个父类可以有多个子类。
- 获取结构:子类获取父类声明的属性和方法。即使父类中声明为
private的成员,子类也继承了(内存中存在),只是由于封装限制导致无法直接访问。 - Object类:Java中所有的类都直接或间接继承自
java.lang.Object。若未显式指定父类,则默认继承 Object 类。
访问父类成员的技巧
当子类需要访问父类成员(特别是受保护和公开成员)时,可通过构造函数初始化或使用 super 关键字。需注意,权限修饰符限制了跨包访问,测试类若在独立包中,仍需遵循权限规则。
// 父类 Father.java
public class Father {
private double ownMoney = 2000;
protected double money = 5000;
public String name = "老张";
}
// 子类 Son.java (假设在同包或具备访问权限的上下文中)
public class Son extends Father {
public Son(String name, double money) {
super.name = name; // 赋值父类公开属性
super.money = money; // 赋值父类受保护属性
}
// 封装方法来操作受保护属性
public void setMoney(double money) {
super.money = money;
}
public double getMoney() {
return super.money;
}
}
// 测试类
public class Test {
public static void main(String[] args) {
Son son = new Son("小张", 3000);
System.out.println(son.getMoney());
}
}
3. 多态性 (Polymorphism)
多态性是面向对象的重要特征,指“同一行为具有多种不同表现形式”。在Java中,主要体现为对象的多态性。
多态的前提条件
- 存在类的继承或接口实现关系。
- 子类重写了父类的方法(方法重写 Override)。
- 父类引用指向子类对象(向上转型)。
虚拟方法调用(编译看左边,运行看右边)
这是多态的核心机制:
- 编译期:编译器检查引用变量声明的类型(左边),决定能调用哪些方法。如果调用子类特有而父类没有的方法,编译会报错。
- 运行期:JVM根据实际创建的堆内存对象类型(右边),执行对应子类重写的方法。
Person p = new Student(); // Person 是编译时类型,Student 是运行时类型
p.getInfo(); // 调用的是 Student 类的 getInfo() 方法
注意事项
- 不适用于属性:多态下,访问属性时编译和运行都看“左边”(父类引用的类型)。
- 向下转型的风险:若要调用子类特有的方法,必须进行强制类型转换(向下转型)。若无关联的两个类进行强转(如将 Man 强转为 Woman),会抛出
ClassCastException。使用前务必使用instanceof关键字进行类型检查。
4. 抽象性 (Abstraction)
当多个类具有相同的功能签名但实现逻辑不同时,可以使用抽象类来提取共性,避免代码冗余。
抽象类的特点
- 定义:使用
abstract关键字修饰。 - 实例化:抽象类不能直接通过
new实例化,它是天生父类。 - 内容组成:可以包含抽象方法(无方法体),也可以包含普通方法和具体属性。
- 继承要求:子类若不想成为抽象类,必须重写父类中的所有抽象方法。
抽象方法的规范
- 不可修饰:构造方法、静态方法(static)、私有方法(private)不能定义为抽象方法。
- 访问权限:抽象方法不能使用
private修饰,否则子类无法重写。
匿名子类的妙用
可以直接创建抽象类的匿名子类对象,这在需要快速实现一个接口或抽象类且不再复用时非常有用。
Person p = new Person() {
@Override
public void eat() {
System.out.println("吃特制食物");
}
};
p.eat(); // 输出:吃特制食物
总结
封装通过私有化和Getter/Setter控制访问权限,保障数据安全;继承通过代码复用减少了冗余,建立了类的层级结构;多态通过父类引用指向子类对象实现了接口的统一与实现的多样,提升了程序的灵活性;抽象类则作为一种设计蓝图,规范了子类必须提供的行为。这四者相辅相成,构成了Java面向对象编程坚实的基础。 以上就是Java面向对象的封装、继承、多态、抽象的详细内容,更多关于Java编程基础与设计的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













