Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Java基础-封装、继承、多态

Java基础-封装、继承、多态

作者头像
越陌度阡
发布于 2024-05-24 07:07:08
发布于 2024-05-24 07:07:08
1.1K00
代码可运行
举报
运行总次数:0
代码可运行

Java是一门面向对象非常好的语言,拥有面向对象的三个基本特征:封装、继承、多态。

1. 什么是封装?

封装就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。

1.1. 封装的规则

1. 将类的某些信息隐藏在类的内部,不允许外部程序直接访问;

2. 通过该提供的方法来实现对隐藏信息的操作和访问;

1.2. 封装的步骤

1. 修改属性为私有设为private;

2. 创建getter和setter方法,设为public用于属性的读写;

3. 在gettter和setter方法中加入属性控制语句,用于对属性的合法进行判断;

1.3. 封装的实现

1. 封装一个学生类

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Student {

    private String name;
    private int age;

    // 获取学生姓名
    public String getName() {
        return name;
    }
    // 设置学生姓名
    public void setName(String name) {
        this.name = name;
    }

    // 获取学生年龄
    public int getAge() {
        return age;
    }

    // 设置学生年龄
    public void setAge(int age) {
        this.age = age;
    }

    // 无参构造函数
    public Student(){


    }

    // 有参构造函数
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

}

2. 调用学生类实例化对象

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class StudentTest {
    public static void main(String[] args){
        // 实例化一学生
        Student student = new Student();
        // 设置学生姓名
        student.setName("aiguangyuan");
        // 设置学生年龄
        student.setAge(30);
    }
}

2. 什么是继承?

继承是面向对象的三大特性之一,可以使子类具有父类的属性和方法,还可以在子类中重新定义、追加属性和方法。当多个类中存在相同的属性和方法,使用继承模式将每个子类相同代码直接抽取出来放到父类中。

2.1. 继承的相关概念及实现

1. 父类:也被称为基类、超类

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package aiguangyuan.test;

public class Parent {

    protected   String name;
    protected   int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

2. 子类:也被称为派生类

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package aiguangyuan.test;

public class Son extends Parent{
    public void  work(){
        System.out.println("我是"+this.name+",今年"+this.age+"岁,我正在写代码");
    }
}

3. 写一个类进行测试

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package aiguangyuan.test;

public class Test {

    public static void main(String[] args) {

        Son son = new Son();

        son.setAge(20);
        son.setName("Mark");

        int age = son.getAge();
        String name = son.getName();

        System.out.println(age);
        // 20
        System.out.println(name);
        // Mark
        son.work();
        // 我是Mark,今年20岁,我正在写代码

    }
}
2.2. 继承的优缺点

1. 继承的优点

提高了代码的复用性,多个类相同的成员属性和方法可以放到一类中;

提高了代码的复用性,如果方法的代码需要修改,只需修改一处即可;

2. 继承的缺点;

继承让类与类之间产生了关系,类的耦合性也增加了,当父类发生变化时,子类也不得不跟着变化,削弱了子类的独立性;

2.3. 继承中变量的访问规则

1. 首先在子类局部范围中查找;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package aiguangyuan.test;
public class Son extends Parent{
    public int age = 20;
    public void show(){
         int age = 22;
         System.out.println("当前的年龄为:"+age);
         // 当前的年龄为:22
    }
}

2. 如果子类局部范围中查找没有,就在子类成员范围查找;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package aiguangyuan.test;
public class Son extends Parent{
    public int age = 20;
    public void show(){
         // int age = 22;
         System.out.println("当前的年龄为:"+age);
         // 当前的年龄为:20
    }
}

3. 如果在子类局部范围和子类成员范围查找都没有,就在父类成员查找;

父类代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package aiguangyuan.test;
public class Parent {
    public  int age = 18;
    public  int height = 175;
    public  int weight = 120;
}

子类代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package aiguangyuan.test;
public class Son extends Parent{
    // public int age = 20;
    public void show(){
         // int age = 22;
         System.out.println("当前的年龄为:"+age);
         // 当前的年龄为:18
    }
}

4. 子类局部范围中访问子类成员范围使用this;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package aiguangyuan.test;
public class Son extends Parent{
    public int age = 20;
    public void show(){
         int age = 22;
         System.out.println("当前的年龄为:"+this.age);
         // 当前的年龄为:20
    }
}

5. 子类局部范围中访问父类成员范围使用super;

父类代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package aiguangyuan.test;
public class Parent {
    public  int age = 18;
    public  int height = 175;
    public  int weight = 120;
}

子类中使用父类成员:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package aiguangyuan.test;
public class Son extends Parent{
    public int age = 20;
    public void show(){
         int age = 22;
         System.out.println("当前的年龄为:"+super.age);
         // 当前的年龄为:18
    }
}
2.4. 继承中构造方法的访问规则

子类中所有的构造方法默认都会访问父类中的无参构造方法。

因为子类会继承父类中的数据,所以子类初始化之前,需要对父类进行初始化。

每个子类构造方法的第一句默认都是super()。

如果父类中没有无参构造方法,只有带参构造方法,怎么办?

1. 父类中自己单独定义一个无参构造方法;

2. 通过super关键字显示调用父类的有参构造方法;

父类如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package aiguangyuan.temp;
public class Parent {
    // 父类中没有无参构造方法
    public Parent(int age){
        System.out.println("父类中的有参构造方法,参数为:"+age);
    }
}

子类如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package aiguangyuan.temp;
public class Son extends Parent{
    public Son(){
        // 父类中没有无参构造函数,通过super调用父类有参构造函数
        super(48);
        System.out.println("儿子类的无参构造方法");
    }
    public Son(int age){
        // 父类中没有无参构造函数,通过super调用父类有参构造函数
        super(48);
        System.out.println("儿子类的有参构造方法,参数为:"+age);
    }
}
2.5. 继承中的成员方法访问规则

1. 首先在子类范围中查找;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package aiguangyuan.study;
public class Son extends Parent {
    public void study(){
        System.out.println("我是儿子,我很热爱学习");
    }
}

以上是一个儿子类,他继承了父类,里面有一个study方法。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package aiguangyuan.study;
public class Test {
    public static void main(String[] args) {
        Son son = new Son();
        son.study();
        // 我是儿子,我很热爱学习
    }
}

当实例化儿子对象时,调用study方法,首先调用儿子类里面的study方法。

2. 如果在子类中查找没有,就在父类成员查找;

父类如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package aiguangyuan.study;
public class Parent {
    public void study(){
        System.out.println("我是父亲,我很热爱学习");
    }
}

子类如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package aiguangyuan.study;
public class Son extends Parent {
    
}

结果如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package aiguangyuan.study;
public class Test {
    public static void main(String[] args) {
        Son son = new Son();
        son.study();
        // 我是父亲,我很热爱学习
    }
}

3. 如果父类和子类中都没有则会报错;

2.6. 继承中访问关键字的总结

1. this代表本类对象的引用;

2. super代表父类存储空间的标识,可以理解为父类对象的引用;

2.7. 继承中的方法覆写

当子类中出现了和父类一模一样的方法,该方法中需要父类的功能,而又有自己独特的内容,这样就可以通过覆写父类的方法,这样既延续了父类的功能,又定义了自己的内容。

父类如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package aiguangyuan.temp;
public class Phone {
    public  void call(String name){
        System.out.println(name+"手机可以拨打电话");
    }
}

子类如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package aiguangyuan.temp;
public class NewPhone extends Phone{
    @Override // 此注解代表覆写
    public  void  call(String name){
        System.out.println("华为手机支持视频通话");
        super.call(name);
    }
}

结果如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package aiguangyuan.temp;
public class TestPhone {
    public static void main(String[] args) {
        NewPhone newPhone = new NewPhone();
        newPhone.call("诺基亚");
        // 华为手机支持视频通话
        // 诺基亚手机可以拨打电话
    }

}

方法重写注意事项:

1. 私有的方法不能被重写,因为父类中的私有方法子类不能被继承;

2. 子类方法访问权限不能比父类低,可以大于也可以等于,其中公有大于默认,默认大于私有;

2.8. 继承中的权限修饰符

Java中有四种权限修饰符,其中三种有访问权限修饰符,分别为private、public和protected,还有一种不带任何修饰符。

1. private:Java语言中对访问权限限制最窄的修饰符,一般称之为私有的。被其修饰的的类、属性及方法只能被该类的对象访问,其子类不能访问,更不允许跨包访问;

2. default:即不加任何访问修饰符,通常称为默认访问模式。该模式下,只允许在同一个包中进行访问;

3. protect:介于public和private之间的一种访问修饰符,一般称之为保护模式。被其修饰的类、属性及方法只能被类本身的方法及子类访问,即使子类在不同的包中也可以访问;

4. public:Java中访问限制最宽的修饰符,一般称之为公有的。被其修饰的类、属性及方法不仅可以跨类该问,还可以跨包访问;

2.9. 多层继承

在C++语言中,是可以同时继承两个父类的,但是在Java中只支持单继承,如果要继承两个父类,需要分两次分别继承,即多层继承。

3. 什么是多态?

多态是面向对象的三大特征之一,即同一个对象,在不同的时刻表现出来不同的形态。

3.1. 多态的前提和实现

1. 有继承或实现的关系;

2. 子类有对父类的方法进行重写;

3. 父类的引用来自子类对象;

父类代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package aiguangyuan.temp;
public class AnimalParent {
    public  void  eat(){
        System.out.println("这是动物父类中的吃方法");
    }
}

子类代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package aiguangyuan.temp;
public class Dog  extends AnimalParent{
    @Override
    public void  eat(){
        System.out.println("狗类重写了父类的吃方法");
    }
}

多态实现:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package aiguangyuan.temp;

public class AnimalDemo {
    public static void main(String[] args) {

        // 子类的引用来自子类
        // Dog dog = new Dog();
        // dog.eat();

        // 父类的引用来自子类
        AnimalParent animalParent = new Dog();
        animalParent.eat();
        // 狗类重写了父类的吃方法
    }
}
3.2. 多态的访问特点

成员变量:编译看左边,执行看左边;

成员方法:编译看左边,执行看右边;

为什么成员变量和成员方法的访问不一样呢?

这是因为成员方法有重写,而成员变量是没有的。

父类代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package aiguangyuan.test;
public class AnimalParent {
    public int age = 40;
    public  void  eat(){
        System.out.println("我是动物父类中的吃方法");
    }
}

子类代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package aiguangyuan.test;
public class Dog extends AnimalParent{
    public int age = 20;
    public  int weight = 40;
    @Override
    public void eat() {
        System.out.println("我是狗类中的吃方法");
    }

    public  void  show(){
        System.out.println("当前显示的是狗类");
    }
}

执行示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package aiguangyuan.test;
public class AnimalDemo {
    public static void main(String[] args) {

        AnimalParent animalParent = new Dog();

        // System.out.println(animalParent.weight);
        // 编译报错,因为左边的animalParent没有wight属性,所以也无法执行

        // animalParent.show();
        // 编译报错,因为左边的animalParent没有show方法

        animalParent.eat();
        // 执行成功,因为右边的Dog类中有eat方法
    }
}
3.3. 多态的访问优点和缺点

多态的好处:提高了程序的扩展性。

具体的体现:定义方法的时候,使用父类型作为参数,将来在使用的时候,使用具体的子类型参操作。

定义动物父类:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package aiguangyuan.test;
public class AnimalParent {
    public  void  eat(){
        System.out.println("我是动物父类中的吃方法");
    }
}

定义子类的狗类:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package aiguangyuan.test;
public class Dog extends AnimalParent{
    @Override
    public void eat() {
        System.out.println("我是狗类,我在吃屎");
    }
}

定义子类的猫类:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package aiguangyuan.test;
public class Cat extends AnimalParent{
    @Override
    public void eat() {
        System.out.println("我是猫类,我在吃鱼");
    }
}

定义动物的操作类:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package aiguangyuan.test;

public class AnimalOperate {

    //public  void  useCatEat(Cat cat){
    //    cat.eat();
    //}
    //public  void  useDogEat(Dog dog){
    //    dog.eat();
    //}
    //

    // 定义方法的时候,使用父类型作为参数,
    public  void  useAnimal(AnimalParent animalParent){
        animalParent.eat();
    }
    
}

执行示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package aiguangyuan.test;

public class AnimalDemo {
    public static void main(String[] args) {

        // 调用动物操作类
        AnimalOperate animalOperate = new AnimalOperate();


        // 调用猫类中的useCatEat方法
        //animalOperate.useCatEat(new Cat());
        // 我是猫类,我在吃鱼

        // 调用狗类中的useDogEat方法
        //animalOperate.useDogEat(new Dog());
        // 我是狗类,我在吃屎


        // 在使用的时候,使用具体的子类型参操作。

        animalOperate.useAnimal(new Cat());
        // 我是猫类,我在吃鱼
        animalOperate.useAnimal(new Dog());
        // 我是狗类,我在吃屎

        
    }
}

多态的弊端:不能使用子类的特有功能。

3.4. 多态中的转型

1. 向上转型,从子类到父类,父类引用指向子类对象,也是Java中默认的存在方式;

2. 向下转型,从父类到子类,父类引用转为子类对象,这种方式只能显示的强转;

定义父类:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package aiguangyuan.test;
public class AnimalParent {
    public  void  eat(){
        System.out.println("我是动物父类中的吃方法");
    }
}

定义子类狗类:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package aiguangyuan.test;
public class Dog extends AnimalParent{
    @Override
    public void eat() {
        System.out.println("我是狗类,我在吃屎");
    }
    public void showDog(){
        System.out.println("我是小狗");
    }
}

执行示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package aiguangyuan.test;

public class AnimalDemo {
    public static void main(String[] args) {

        Dog dog1 = new Dog();
        dog1.showDog();
        // 我是小狗

        // 多态中,编译阶段是看左边,执行是看右边,向上转型,从子到父
        AnimalParent parent = new Dog();

        // parent中没有showDog方法,如果想调用该方法需要向下转型,从父到子
        Dog dog2 = (Dog) parent;
        dog2.showDog();
        // 我是小狗

    }
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-05-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Java面向对象三大特性(封装、继承、多态)
OOP 语言:也就是面向对象编程。 面向对象的语言有三大特性:封装、继承、多态。三大特性是面向对象编程的核心。下面就来介绍一下面向对象的三大特性。 如果想了解面向对象可以看一下这一篇博客类和对象
全栈程序员站长
2022/09/17
3490
Java面向对象三大特性(封装、继承、多态)
JavaSE/封装、继承、多态
封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互。
用户10788736
2023/10/16
2010
JavaSE/封装、继承、多态
Java面向对象三大特性
利用抽象数据类型将数据和基于数据的操作封装在一起,使其构成一个不可分割的独立实体。 数据被保护在抽象数据类型的内部,尽可能地隐藏内部的细节, 只保留一些对外接口使之与外部发生联系。用户无需知道对象内部的细节, 但可以通过对象对外提供的接口来访问该对象。
李红
2019/06/06
4370
Java面向对象三大特性
Java学习笔记之继承与修饰符
继承是面向对象三大特征之一,可以使得子类具有父类的属性和方法,还可以在子类中重新定义,以及追加属性和方法。
Jetpropelledsnake21
2021/11/30
4430
Java学习笔记之继承与修饰符
JavaSE学习总结(五)——封装,继承,多态很简单
根据文章内容撰写摘要总结。
张果
2018/01/04
1.3K0
JavaSE学习总结(五)——封装,继承,多态很简单
《JavaSE-第九章》之继承与多态
本章重点介绍面向对象的三大特征的继承与多态。现实中某一人类继承了继承了其父母亲的基因,也继承了家产。对应在Jvaa世界中则是如果两个类之间的关系是is-a的关系则构成继承,比如狗是一只动物,狗就继承了动物的属性与行为。自然界中有万千生物,每一种生物都能“走”,都能发出“声音”,但是走的姿势与声音是截然不同的,这就是多态。
用户10517932
2023/10/07
2780
《JavaSE-第九章》之继承与多态
【Java 基础】:三大特征之多态
【Java 基础】类和对象(构造&this&封装&static&代码块)-CSDN博客
IsLand1314
2024/10/15
1420
【Java 基础】:三大特征之多态
java 语言【继承和多态】
Java中使用类对现实世界中实体来进行描述,类经过实例化之后的产物对象,则可以用来表示现实中的实体,但是 现实世界错综复杂,事物之间可能会存在一些关联,那在设计程序是就需要考虑。 比如:狗和猫,它们都是一个动物。 使用Java语言来进行描述,就会设计出:
用户11319080
2024/10/17
1180
java 语言【继承和多态】
09(02)总结final,多态,抽象类,接口
(4)抽象类的练习 A:猫狗案例练习 B:老师案例练习 C:学生案例练习 D:员工案例练习 /* A: 猫狗案例 具体事物:猫,狗 共性:姓名,年龄,吃饭 分析:从具体到抽象 猫: 成员变量:姓名,年龄 构造方法:无参,带参 成员方法:吃饭(猫吃鱼) 狗: 成员变量:姓名,年龄 构造方法:无参,带参 成员方法:吃饭(狗吃肉) 因为有共性的内容,所以就提取了一个父类。动物。 但是又由于吃饭的内容不一样,所以吃饭的方法是抽象的, 而方法是抽象的类,类就必须定义为抽象类。
Java帮帮
2018/03/15
8700
理解多态知识--Java
什么是多态? 多态(polymorphism)就是多种形态,简单来说就是做同一件事情,不同的对象做就会有不一样的结果/状态 或者说就是一个引用调用同一个方法,表示出不一样的行为就叫做多态 多态的实现条件 1、完成向上转型 2、实现方法的重写 3、通过引用调用重写 向上转型 向上转型就是将子类赋值给父类 class Animal{ private String name; private int age; public Animal(String name, in
用户9996207
2023/01/13
2460
Java学习笔记之多态&抽象类&接口
    提供程序的扩展性,定义方法的时候,使用父类型作为参数,在使用的时候,使用具体的子类行参与操作
Jetpropelledsnake21
2021/11/30
3370
Java学习笔记之多态&抽象类&接口
【Java面向对象三大特征——多态】
多态:完成某个行为,当不同对象去完成时会产生出不同的状态。(同一件事,发生在不同对象身上,产生不同的效果。eg:动物吃粮食这个动作,对于猫是吃猫粮,狗是吃狗粮。)
ImAileen
2024/12/04
1600
【Java面向对象三大特征——多态】
JAVA零基础小白上手教程day08-JAVAOOP面向对象
<img src="asseits/龙生九子.jpg" alt="龙生九子" style="zoom: 67%;" />
张哥编程
2024/12/13
690
Javase-11.多态
多态的概念:通俗来说就是多种形态.具体点就是去完成某个行为时,不同的对象去完成会产生不同的状态.
用户11369350
2024/11/19
680
Javase-11.多态
详解Java三大特性——多态
现实事物经常会体现出多种形态,如学生,学生是人的一种,则一个具体的同学张三既是学生也是人,即出现两种形态。
苏先生
2019/05/07
3740
详解Java三大特性——多态
Java基础(八):封装、继承、多态性
概述:私有化类的成员变量,提供公共的get和set方法,对外暴露获取和修改属性的功能
Java微观世界
2025/01/21
1720
Java基础(八):封装、继承、多态性
JAVA17/JAVA21接口和多态机制
如果实现类,同时继承父类,实现接口,父类和接口的方法名、访问权限、返回类型都一样,则“类优先”原则。
张哥编程
2024/12/13
1470
JAVA17/JAVA21接口和多态机制
1.8 封装、继承、多态
面向对象编程语言是对客观世界的模拟,客观世界里成员变量都是隐藏在对象内部的,外界无法直接操作和修改。封装可以被认为是一个保护屏障,防止该类的代码和数据被其他类随意访问。要访问该类的数据,必须通过指定的方式。适当的封装可以让代码更容易理解与维护,也加强了代码的安全性。
ha_lydms
2023/08/09
2010
1.8 封装、继承、多态
面向对象的三大特性讲义
多个类中存在相同属性和行为时, 将这些内容抽取到单独的一个类中, 那么这多个类就无需再定义这些属性和行为了, 只要继承那个类即可. 这个关系, 就叫继承.
用户8870853
2021/08/30
5890
Java核心基础知识:面向对象的三大特性讲义
上述的每一个步骤, 我们都是参与者, 并且需要面对具体的每一个步骤和过程, 这就是面向过程最直接的体现.
用户1880875
2021/08/26
4680
相关推荐
Java面向对象三大特性(封装、继承、多态)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验