封装、继承和多态

简介: 封装、继承和多态

前言


其实封装、继承和多态不仅仅是java的特性,而是所有面向对象程序的三大特性。


一、什么是封装?


封装就是对类内部的实现细节进行隐藏,然后对类外提供公开的接口。


在Java 中主要通过访问权限来实现封装, 访问权限用来控制方法或者属性能否直接在类外使用 。 Java 中提供了四种访问限定符:


1667909560682.jpg

封装一般就是我们把类属性加上private进行修饰,把属性进行私有化。

public class Student {
private String name;
private int age;
private int classid;
}

在这个学生类中,我们把name和age以及classid属性被设置为私有的,那么它只能被这个类访问,而不能被其他类访问,因此信息是隐藏的。为了让外部进行访问,我们还可以为每个属性提供公开的方法:Getter and Setter

1667909579226.jpg

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 int getClassid() {
        return classid;
    }
    public void setClassid(int classid) {
        this.classid = classid;
    }

因此,如果外部类想要访问类中私有成员变量的都必须使用这些getter和setter方法。


封装的优点:良好的包装可以减少耦合;类的内部结构可以自由修改;可以更精确地控制成员变量;隐藏信息和实现细节。


二、什么是继承?


在Java中,可以通过extends关键字申明一个类是从另一个类继承而来的:

class 父类 {
}
class 子类 extends 父类 {
}

继承其实是父类对子类的共性的抽取, 实现代码的复用。

1667909615801.jpg

1667909622888.jpg

1667909634271.jpg

子类中访问父类的成员变量

如果访问的成员变量子类中有,优先访问自己的成员变量。

如果访问的成员变量子类中无,则访问父类继承下来的,如果父类也没有定义,则编译报错。

如果访问的成员变量与父类中成员变量同名,则优先访问自己的。

成员变量访问遵循就近原则,自己有优先自己的,如果没有则向父类中找 。

子类中访问父类的成员方法

通过子类对象访问父类与子类中不同名方法时,优先在子类中找,找到则访问,否则在父类中找,找到 则访问,否则编译报错。

通过派生类对象访问父类与子类同名方法时,如果父类和子类同名方法的参数列表不同 ( 重载 ) ,根据调用方法适传递的参数选择合适的方法访问,如果没有则报错;

如果子类中存在与父类中相同的成员时,那么在子类中访问父类相同名称的成员就需要使用super关键字。super关键字的主要作用:在子类方法中访问父类的成员。了解super可以参考这篇文章。

super和this有什么区别?-java_crazy__xieyi的博客-CSDN博客


三、什么是多态?


一个引用调用同一个方法,因为这个引用 引用的对象不一样,导致调用这个方法,所表现出来的行为不一样。这种思想就叫做多态。


在 java 中要实现多态,必须要满足如下几个条件,缺一不可:

1. 必须在继承体系下

2. 子类必须要对父类中方法进行重写

3. 通过父类的引用调用重写的方法

多态体现:在代码运行时,当传递不同类对象时,会调用对应类中的方法。

public class Animal {
    String name; 
    int age;
    public Animal(String name, int age){
        this.name = name;
        this.age = age;
    }
    public void eat(){ //重写了eat方法
        System.out.println(name + "吃饭");
    }
}
public class Cat extends Animal{
    public Cat(String name, int age){
        super(name, age);
    }
    @Override   //重写了eat方法
    public void eat(){
        System.out.println(name+"吃鱼~~~");
    }
}
public class Dog extends Animal {
    public Dog(String name, int age){
        super(name, age);
    }
    @Override
    public void eat(){
        System.out.println(name+"吃骨头~~~");
    }
}
///分割线//
public class TestAnimal {
    // 编译器在编译代码时,并不知道要调用Dog 还是 Cat 中eat的方法
    // 等程序运行起来后,形参a引用的具体对象确定后,才知道调用那个方法
    // 注意:此处的形参类型必须时父类类型才可以
    public static void eat(Animal a){
        a.eat();
    }
    public static void main(String[] args) {
        Cat cat = new Cat("元宝",2);  
        Dog dog = new Dog("小七", 1);
        eat(cat); //元宝吃鱼
        eat(dog); //小七吃骨头
    }
}


在上述代码中 , 分割线上方的代码是 类的实现者 编写的 , 分割线下方的代码是 类的调用者 编写的 .

当类的调用者在编写 eat 这个方法的时候 , 参数类型为 Animal ( 父类 ), 此时在该方法内部并 不知道 , 也不关注 当前的 a 引用指向的是哪个类型 ( 哪个子类 ) 的实例 . 此时 a 这个引用调用 eat 方法可能会有多种不同的表现 ( 和 a 引用的实例相关), 这种行为就称为 多态。


相关文章
|
11月前
|
XML Java 数据格式
SpringBoot入门(8) - 开发中还有哪些常用注解
SpringBoot入门(8) - 开发中还有哪些常用注解
138 0
|
存储 编译器 C语言
【C++11特性篇】模板的新一力将:可变参数模板 [全解析]
【C++11特性篇】模板的新一力将:可变参数模板 [全解析]
|
C++
C++中的封装、继承与多态:深入理解与应用
C++中的封装、继承与多态:深入理解与应用
362 1
|
SQL 存储 数据库
MSSQL性能调优实战:索引优化、SQL语句精调与高效并发处理
在Microsoft SQL Server(MSSQL)的性能调优征途中,索引优化、SQL语句的精细调整以及高效并发处理是三大核心策略
|
10月前
|
机器学习/深度学习 人工智能 自然语言处理
人工智能在医疗诊断中的应用与前景####
本文深入探讨了人工智能(AI)技术在医疗诊断领域的应用现状、面临的挑战及未来发展趋势。通过分析AI如何辅助医生进行疾病诊断,提高诊断效率和准确性,以及其在个性化医疗中的潜力,文章揭示了AI技术对医疗行业变革的推动作用。同时,也指出了数据隐私、算法偏见等伦理问题,并展望了AI与人类医生协同工作的前景。 ####
699 0
|
8月前
|
机器学习/深度学习 测试技术 计算机视觉
RT-DETR改进策略【Conv和Transformer】| ICCV-2023 iRMB 倒置残差移动块 轻量化的注意力模块
RT-DETR改进策略【Conv和Transformer】| ICCV-2023 iRMB 倒置残差移动块 轻量化的注意力模块
184 14
RT-DETR改进策略【Conv和Transformer】| ICCV-2023 iRMB 倒置残差移动块 轻量化的注意力模块
画图
画图。
515 15
|
存储 缓存 分布式计算
HDFS优化方案
HDFS优化方案
|
负载均衡 算法 Java
分布式系列教程(10) -分布式协调工具Zookeeper(负载均衡原理实现)
分布式系列教程(10) -分布式协调工具Zookeeper(负载均衡原理实现)
236 0