Java面向对象的三大特征

本文详细探讨了Java面向对象的三大特性:封装、继承和多态。封装通过访问控制符和getter、setter方法保护类的内部数据;继承允许类的重用并提供了多层继承的机制;多态则是通过方法重写实现动态绑定,提高代码的灵活性和可扩展性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一说到java面向对象编程,我们就想到面向对象的三大特性,封装,继承和多态。封装是 Java 类的编写规范、继承是类与类之间联系的一种形式,而多态为系统组件或模块之间解耦提供了解决方案。

封装

概念:隐藏类的属性和具体实现细节,只提供相关的接口和方法来对隐藏信息进行控制和修改。

封装的思想保证了类内部数据结构的完整性,使用户无法轻易直接操作类的内部数据,这样降低了对内部数据的影响,提高了程序的安全性和可维护性。

封装的目的:
  • 只能通过规定的方法访问数据
  • 隐藏类的实现细节
  • 方便加入控制语句
  • 方便实现修改
访问控制符:

在进行封装的时候做好访问权限控制,目前在java中有四种访问控制以及它们的访问范围如下表所示:
在这里插入图片描述
default拒绝一切包外访问,protected接受包外的子类访问。

getter和setter方法:
gettersetter
用于获取属性的值用于修改属性的名
public class Demo1 {
    
    public String name;        // 公有的
        
    protected int age;        // 受保护的
    
    char sex;                // 默认的
    
    private int num;        // 私有的
    
    //获取私有成员num值   
    public int getNum() {
        return num;
    }
    
    // 设置私有成员num的值
    public void setNum(int num) {
        this.num = num;
    }
}

继承

概念:继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或类从父类继承方法,使得子类具有父类相同的行为。

继承的特点:
  • 继承鼓励类的重用
  • 继承可以多层继承
  • 一个类只能继承一个父类
  • 父类中private修饰的不能被继承
  • 构造方法不能被继承
使用继承:

1.编写父类
有公共的属性和方法

package test;
/**
 *     父类
 *
 */
public class Father {
    
    //父类中的成员属性
    public String name;    
    public int age;
    public char sex;
    
    /**
     * 父类中的成员方法
     */
    public void say(){
        System.out.println("我会说话");
    }

    public void eat(){
        System.out.println("我会吃饭");
    }    
}

2.编写子类,继承父类

  • 子类继承父类时只能继承一个父类
  • 继承的关键字 extends
package test;
pulic class Son extends Father {
    
    
}
子类访问父类成员
  • 访问父类构造方法
    super(); 父类无参的构造方法
    super(name); 父类有参的构造方法

  • 访问父类属性
    super.name;

  • 访问父类方法
    super.方法名();

class Animal {
    public String name;
    public Animal(String name) {
        this.name = name;
    }
    public void eat(String food) {
        System.out.println(this.name + "正在吃" + food);
    }
}
class Cat extends Animal {
    public Cat(String name) {
// 使用 super 调用父类的构造方法.
        super(name);
    }
}
class Bird extends Animal {
    public Bird(String name) {
        super(name);
    }
    public void fly() {
        System.out.println(this.name + "正在飞 ︿( ̄︶ ̄)︿");
    }
}
public class Test {
    public static void main(String[] args) {
        Cat cat = new Cat("小黑");
        cat.eat("猫粮");
        Bird bird = new Bird("圆圆");
        bird.fly();
    }
}

如果我们把字段设为 private, 子类不能访问. 但是设成 public, 又违背了我们 “封装” 的初衷.两全其美的办法就是 protected 关键字

  • 对于类的调用者来说, protected 修饰的字段和方法是不能访问的
  • 对于类的子类和同一个包的其他类来说, protected 修饰的字段和方法是可以访问的

多层继承:即子类还可以进一步的再派生出新的子类 。

经我们学习过 final 关键字, 修饰一个变量或者字段的时候, 表示常量 (不能修改) .final 关键字也能修饰类, 此时表示被修饰的类就不能被继承.

super关键字;爱访问父类的成员

  • super只能出现在子类的方法和构造方法中;
  • super调用构造方法时,只能是第一句;
  • super不能访问法父类的private成员;
继承的限制和初始化顺序

子类可以继承父类的所有资源吗?
不能被继承的父类成员:

  • private成员
  • 子类与父类不在同包,使用默认访问权限的成员
  • 构造方法

多重继承关系的初始化顺序是怎样的?

在这里插入图片描述

多态

概念:指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式

多态的三个必要条件:
一、要有继承;
二、要有重写;
三、父类引用指向子类对象。

多态的实现方式:接口实现,继承父类进行方法重写,同一个类中进行方法重载。
向上转型

Bird bird = new Bird("圆圆");
Animal bird2 = bird;
// 或者写成下面的方式
Animal bird2 = new Bird("圆圆") 

此时 bird2 是一个父类 (Animal) 的引用, 指向一个子类 (Bird) 的实例. 这种写法称为 向上转型.

当子类和父类中出现同名方法的时候, 再去调用会出现什么情况呢

package package2_17;
class Animal {
    protected String name;
    public Animal(String name) {
        this.name = name;
    }
    public void eat(String food) {
        System.out.println("我是一只小动物");
        System.out.println(this.name + "正在吃" + food);
    }
}
class Cat extends Animal {
    public Cat(String name) {
// 使用 super 调用父类的构造方法.
        super(name);
    }
}
class Bird extends Animal {
    public Bird(String name) {
        super(name);
    }
    public void eat(String food) {
        System.out.println("我是一只小鸟");
        System.out.println(this.name + "正在吃" + food);
    }
}
public class Test {
    public static void main(String[] args) {
        Animal animal1 = new Animal("圆圆");
        animal1.eat("谷子");
        Animal animal2 = new Bird("扁扁");
        animal2.eat("谷子");
    }
}

在这里插入图片描述

  • animal1 和 animal2 虽然都是 Animal 类型的引用, 但是 animal1 指向 Animal 类型的实例, animal2 指向Bird 类型的实例.
  • 针对 animal1 和 animal2 分别调用 eat 方法, 发现 animal1.eat() 实际调用了父类的方法, 而animal2.eat() 实际调用了子类的方法

在 Java 中, 调用某个类的方法, 究竟执行了哪段代码 (是父类方法的代码还是子类方法的代码) , 要看究竟这个引用指向的是父类对象还是子类对象. 这个过程是程序运行时决定的(而不是编译期), 因此称为动态绑定

方法重写

子类实现父类的同名方法, 并且参数的类型和个数完全相同, 这种情况称为 覆写/重写/覆盖(Override).
注意事项:

  1. 重写和重载完全不一样. 不要混淆.
  2. 普通方法可以重写, static 修饰的静态方法不能重写.
  3. 重写中子类的方法的访问权限不能低于父类的方法访问权限.

重写和重载的区别:
从字面上看,重写就是重新写一遍的意思。其实就是在子类中把父类本身有的方法重新写一遍。
在一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同甚至是参数顺序不同)则视为重载

区别重载重写
概念方法名称相同,参数的类型及个数不同方法名称,返回值类型,参数类型及个数完全相同
范围一个类继承关系
限制无限制要求子类的方法的访问权限不能低于父类的方法访问权限

使用多态的好处是什么?
1) 类调用者对类的使用成本进一步降低.

  • 封装是让类的调用者不需要知道类的实现细节.
  • 多态能让类的调用者连这个类的类型是什么都不必知道, 只需要知道这个对象具有某个方法即可.

2) 能够降低代码的 “圈复杂度”, 避免使用大量的 if - else

3) 可扩展能力更强.

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值