封装,继承,多态【Java面向对象知识回顾①】

简介: 本文回顾了Java面向对象编程的三大特性:封装、继承和多态。封装通过将数据和方法结合在类中并隐藏实现细节来保护对象状态,继承允许新类扩展现有类的功能,而多态则允许对象在不同情况下表现出不同的行为,这些特性共同提高了代码的复用性、扩展性和灵活性。

封装,继承,多态

① 封装

封装是面向对象编程中最基本的特征之一,它将数据和操作数据的方法封装在一个单独的类中。通过封装,可以隐藏对象的内部细节,只暴露出必要的接口供其他对象进行交互,从而实现了信息的隐藏和保护。

简单的说,就是将对象的属性Private私有化提供对应的getter和setter方法,方便操控对象的属性,然后暴露出需要交互的接口。

为什么使用封装?

封装的特点:

  • 对成员变量实行更准确的控制
  • 封装可以隐藏内部程序实现的细节
  • 良好的封装能够减少代码之间的耦合度
  • 外部成员无法修改已封装好的程序代码
  • 方便数据检查,有利于保护对象信息的完整性,同时也提高程序的安全性。
  • 便于修改,提高代码的的可维护性。
public class Student {
   

    private String name;
    private String sid;

    public String getName() {
   
        return name;
    }

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

    public String getSid() {
   
        return sid;
    }

    public void setSid(String sid) {
   
        this.sid = sid;
    }
}

② 继承

继承是面向对象编程中的另一个重要特征,它允许一个类继承另一个类的属性和方法,从而实现代码的重用和扩展性。被继承的类称为父类(或超类),继承这个类的类称为子类。子类可以继承父类的所有非私有属性和方法,并可以在其基础上添加新的属性和方法。

继承的注意事项:

  • 只支持单继承,但可以多级继承,子类的父类可以再继承其他的类
  • 子类可以拥有父类的非私有的属性和方法
  • 子类可以拥有自己的属性和方法
  • 子类可以重写覆盖父类的方法
public class DemoInherit {
   
    public static void main(String[] args) {
   
        Fu fu = new Fu("张三");
        fu.showMoney();
        Zi zi = new Zi("张小明");
        zi.showMoney();
    }
}

class Fu{
   
   public Double money = 11000.1;
   private String name;

   private void showFuMoney(){
   
       System.out.println(money);
   }

   public void showMoney(){
   
       System.out.println("Fu:"+this.money);
   }

    public Fu() {
   
    }

    public Fu( String name) {
   
        this.name = name;
    }
}

class Zi extends Fu{
   

    private String name;

    public Double money = 100.1;

    @Override
    public void showMoney() {
   
        super.showMoney();
        System.out.println("Zi:总金额"+this.money);
    }

    public Zi() {
   
    }

    public Zi(String name) {
   
        this.name = name;
        this.money += super.money;
    }
}

重写 override

重写是子类对父类的允许访问方法的实现过程进行重新编写,方法名,返回值和形参都不能改变。

class People{
   

    public void run(){
   
        System.out.println("人在奔跑");
    }
}

class Student extends People{
   

    @Override
    public void run() {
   
        // super.run(); super关键字指向父类的引用
        System.out.println("学生在奔跑");
    }
}

重写的规则:

  1. 参数列表必须与被重写方法一致
  2. 访问权限不能比父类中被重写的方法的访问权限更低(public>protected>default>private)。
  3. 父类成员的方法只能被其子类重写
  4. 被final修饰的方法不能被重写
  5. 构造方法不能被重写

重载 overload

重载是指,在同一个类中,方法名字相同,而参数不同。返回类型可以相同也可以不同。每个重载的方法的参数列表必须不同。
重载规则:

  1. 被重载的方法必须改变参数列表(参数个数或者类型不一样或者参数列表的顺序不一致)
  2. 被重载的方法可以改变返回值类型
  3. 被重载的方法可以改变修饰符
public class Dog {
   

    public void run(){
   
        System.out.println("小狗在慢悠悠的run");
    };

    protected void run(String toy){
   
        System.out.println("小狗在run的过程中,捡到了你扔出的"+toy);
    }

    private String run(String toy,int size){
   
        System.out.println("小狗在run的过程中,捡到了你扔出的"+toy+",并摇了"+size+"次尾巴");
        return toy+","+size;
    }

    // 参数列表顺序不一致 若是同种数据类型的话无法完成重载
    private String run(int size,String toy){
   
        System.out.println("小狗在run的过程中,捡到了你扔出的"+toy+",并摇了"+size+"次尾巴");
        return toy+","+size;
    }

    public static void main(String[] args) {
   
        Dog dog = new Dog();
        dog.run();
        dog.run("飞盘");
        String rs1 = dog.run("皮球", 3);
        String rs2 = dog.run( 3,"皮球");
    }

}

super this 关键字

super()关键字的用法:

  • 子类的成员方法中,访问父类的成员变量。
  • 子类的成员方法中,访问父类的成员方法。
  • 子类的构造方法中,访问父类的构造方法。

this关键字用法:

  • 本类成员方法中,访问本类的成员变量。
  • 本类成员方法中,访问本类的另一个成员方法。
  • 本类的构造方法中,访问本类的另一个构造方法。

注意:

  • this关键字同super一样,必须在构造方法的第一个语句,且是唯一的。
  • this与super不能同时存在。

③ 多态

多态是面向对象的第三个特征,它允许一个对象在不同的情况下表现出不同的行为。
多态分为编译时多态和运行时多态。编译时多态是通过方法重载来实现的,而运行时多态是通过方法重写和向上转型来实现的。

多态的特点:

  1. 消除类型之间的耦合关系,实现低耦合
  2. 灵活性
  3. 可扩充性
  4. 可替换性

向上转型

格式: 父类名称 对象名 = new 子类名称(); 含义:右侧创建一个子类对象,将它当作父类使用
缺点:一旦向上转型,子类中原本特有的方法就不能再被调用了。

public class MultiDemo {
   
    public static void main(String[] args) {
   
        // 向上转型
        Animal dog = new Dog();
        dog.eat(); // 小狗吃。。。。
        //  dog.run(); 向上转型后,Dog类对象无法再调用其特与的方法( run() 方法)

        Animal cat = new Cat();
        cat.eat();
        //  cat.sound(); 同理向上转型后,cat无法再调用自己特有的方法

        // 向下转型
        Cat catDown = (Cat) cat;
        catDown.sound(); // 小猫 喵喵喵
        catDown.eat(); // 小猫吃。。。。

        // 下面是错误的操作,将向上转型的dog再向下转型为cat,编译时是无法发现错误的,运行时才会出现错误
        // 向下转型 一定要记得该对象的初始值类型是啥,否则会抛异常 ClassCastException
        Cat catDownError = (Cat) dog;
        catDownError.sound();

    }

}
// 动物类-父类
class Animal{
   
    public void eat(){
   
        System.out.println("动物吃。。。。");
    }
}

// Dog类 
class Dog extends Animal{
   
    @Override
    public void eat() {
   
        // super.eat();
        System.out.println("小狗吃。。。。");
    }

    public void run(){
   
        System.out.println("小狗跑........");
    }

}
// Cat类
class Cat extends Animal{
   
    @Override
    public void eat() {
   
        // super.eat();
        System.out.println("小猫吃。。。。");
    }

    public void sound(){
   
        System.out.println("小猫 喵喵喵");
    }
}

多态中,编译看左边,运行看右边,解释如下.

  1. 编译看左边
    • 在编译时,编译器主要关注的是代码的静态结构。
    • 编译器会检查类型,以确保在编译期间类型是正确的。
    • 例如,当你在代码中调用一个方法时,编译器会检查该方法是否真的存在于你正在调用的对象的类或其父类中。如果存在,那么这个方法可以被调用。如果不存在,编译器将报错。
  2. 运行看右边
    • 在运行时,实际的对象实例决定了实际的行为。
    • 这是多态的核心:一个接口可以有多种实现,而实际的行为在运行时由对象的实际类型决定。
    • 例如,如果你有一个父类和两个子类,都实现了同一个方法。当你通过父类引用调用这个方法时,实际执行的是哪个子类的实现,取决于引用所指向的实际对象。

yuque_diagram.jpg


小结

封装:隐藏对象内部的细节,只暴露出必要的接口去交互,实现了信息的隐藏与保护。(简单的说,就是将对象独有的数据private掉,将公共的方法接口public出去,然后提供getter和setter方法)

继承:允许一个类继承另一个类的方法和属性,实现代码的复用性和扩展。子类只能继承父类非private的成员方法和成员属性。子类可以重写父类允许子类方法的方法,重写的注意点,即结构不变,内核变(方法体根据自己的业务去更改,方法的返回值,方法名参数值列表均不可以变。和继承相关的两个关键字:super和this,分别是指向父类的引用和本类的引用。

多态:多态分为编译时多态和运行时多态,编译时多态即方法的重载运行时多态是指方法的重写和**向上转型。多态提高了程序的扩展性和灵活性。**需要注意的是,向上转型后,子类无法再使用内部特有的方法,如果想使用的话,再向下转型,向下转型时,需要注意实际类型是否匹配,不匹配会抛出 ClassCastException 异常。

相关文章
|
2天前
|
Java 关系型数据库 数据库
面向对象设计原则在Java中的实现与案例分析
【10月更文挑战第25天】本文通过Java语言的具体实现和案例分析,详细介绍了面向对象设计的五大核心原则:单一职责原则、开闭原则、里氏替换原则、接口隔离原则和依赖倒置原则。这些原则帮助开发者构建更加灵活、可维护和可扩展的系统,不仅适用于Java,也适用于其他面向对象编程语言。
8 2
|
7天前
|
Java 开发者
在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口
【10月更文挑战第20天】在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口。本文揭示了这两种方式的微妙差异和潜在陷阱,帮助你更好地理解和选择适合项目需求的线程创建方式。
11 3
|
7天前
|
Java
在Java多线程编程中,实现Runnable接口通常优于继承Thread类
【10月更文挑战第20天】在Java多线程编程中,实现Runnable接口通常优于继承Thread类。原因包括:1) Java只支持单继承,实现接口不受此限制;2) Runnable接口便于代码复用和线程池管理;3) 分离任务与线程,提高灵活性。因此,实现Runnable接口是更佳选择。
19 2
|
7天前
|
Java
Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口
【10月更文挑战第20天】《JAVA多线程深度解析:线程的创建之路》介绍了Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口。文章详细讲解了每种方式的实现方法、优缺点及适用场景,帮助读者更好地理解和掌握多线程编程技术,为复杂任务的高效处理奠定基础。
16 2
|
7天前
|
Java 开发者
Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点
【10月更文挑战第20天】Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点,重点解析为何实现Runnable接口更具灵活性、资源共享及易于管理的优势。
18 1
|
11天前
|
存储 Java 测试技术
Java零基础-多态详解
【10月更文挑战第10天】Java零基础教学篇,手把手实践教学!
14 4
|
16天前
|
Java 编译器 程序员
Java多态背后的秘密:动态绑定如何工作?
本文介绍了Java中多态的实现原理,通过动态绑定和虚拟方法表,使得父类引用可以调用子类的方法,增强了代码的灵活性和可维护性。文中通过具体示例详细解析了多态的工作机制。
27 4
|
18天前
|
Java 测试技术 编译器
Java零基础-继承详解!
【10月更文挑战第4天】Java零基础教学篇,手把手实践教学!
19 2
|
22天前
|
Java 编译器
在Java中,关于final、static关键字与方法的重写和继承【易错点】
在Java中,关于final、static关键字与方法的重写和继承【易错点】
20 5
|
22天前
|
Java
java继承和多态详解
java继承和多态详解
35 5