七、面向对象编程(中级)

2024-08-27 09:44
文章标签 面向对象编程 中级

本文主要是介绍七、面向对象编程(中级),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 一、IDEA
    • 1.1 IDEA下载安装
    • 1.2 IDEA的使用
    • 1.3 IDEA常用的快捷键
  • 二、包
    • 2.1 包的基本介绍
    • 2.2 包的本质分析
    • 2.3 包的命名
    • 2.4 常用的包
    • 2.5 如何引入包
  • 三、访问修饰符
  • 四、面向对象的三大特征
    • 4.1 封装
    • 4.2 继承
      • 4.2.1 为什么需要继承
      • 4.2.2 继承的基本介绍
      • 4.2.3 继承的深入讨论/细节问题
      • 4.2.4 继承的本质分析(内存分析,重要)
    • 4.3 super关键字
    • 4.4 super与this的比较
    • 4.5 方法重写/覆盖(override)
    • 4.6 方法重写与重载比较
    • 4.7 多态
      • 4.7.1 基本介绍
      • 4.7.2 多态注意事项和细节讨论
      • 4.7.3 java的动态绑定机制(非常非常重要)
      • 4.7.4 多态的应用
  • 五、Object类详解
    • 5.1 equals方法
    • 5.2 hashCode方法
    • 5.3 toString()方法
    • 5.4 finalize方法
  • 六、断点调试
  • 七、细节知识
    • 7.1 访问修饰符
    • 7.2 继承的细节
    • 7.3 继承的本质分析(内存分析,重要)
    • 7.4 super细节
    • 7.5 方法重写的细节
    • 7.6 多态的理解
    • 7.7 java的动态绑定机制(非常非常重要)

一、IDEA

1.1 IDEA下载安装

在这里插入图片描述

1.2 IDEA的使用

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

1.3 IDEA常用的快捷键

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

二、包

2.1 包的基本介绍

在这里插入图片描述

2.2 包的本质分析

在这里插入图片描述

2.3 包的命名

在这里插入图片描述

2.4 常用的包

在这里插入图片描述

2.5 如何引入包

在这里插入图片描述

建议:我们需要使用哪个类就导入哪个类,不建议使用 * 导入
在这里插入图片描述

在这里插入图片描述

三、访问修饰符

在这里插入图片描述

在这里插入图片描述

注:上述多个访问范围之间是或的关系(如:protected修饰的属性或方法可以被 同类同包子类 访问);另外 同包 指的是 完全相同的包路径(子包路径不算相同)

四、面向对象的三大特征

  • 基本介绍
    面向对象编程有三大特征:封装继承多态

4.1 封装

  • 基本介绍
    在这里插入图片描述

  • 封装的理解和好处
    在这里插入图片描述

  • 封装的实现步骤
    在这里插入图片描述

  • 快速入门
    在这里插入图片描述

public class Hello {public static void main(String[] args) {Person person = new Person();person.setAge(900);}
}class Person {public String name;private int age;private double salary;private String job;public Person() {}public Person(String name, int age, double salary, String job) {setAge(age);setJob(job);setName(name);setSalary(salary);}public void setName(String name) {if (name.length() >= 2 && name.length() <= 6) {this.name = name;return;}System.out.println("输入的名字长度必须在2-6之间");}public void setAge(int age) {if (age >= 1 && age <= 120) {this.age = age;return;}System.out.println("年龄必须在1-120");}public void setSalary(double salary) {this.salary = salary;}public void setJob(String job) {this.job = job;}public String getName() {return name;}public int getAge() {return age;}public double getSalary() {return salary;}public String getJob() {return job;}
}

4.2 继承

4.2.1 为什么需要继承

在这里插入图片描述

4.2.2 继承的基本介绍

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

4.2.3 继承的深入讨论/细节问题

在这里插入图片描述

// 基础父类
package com.extends_;public class Base {// 4个属性public int n1 = 100;protected int n2 = 200;int n3 = 300;private int n4 = 400;public int getN4() { // 构建公共方法使子类可以访问私有属性return this.n4;}public Base() {}public void test100() {System.out.println("test100()....");}protected void test200() {System.out.println("test200()....");}void test300() {System.out.println("test300()....");}private void test400() {System.out.println("test400()....");}
}
// 子类(与父类同包)
package com.extends_;public class Sub extends Base {public Sub() {}public void sayOk() {// 非私有的属性和方法可以在子类直接访问// 私有属性和方法不能在子类直接访问(n4无法直接访问)System.out.println(n1 + "" + n2 + "" + n3);int n4 = getN4();// 通过父类的公共方法对私有属性进行访问System.out.println("n4:"+n4);test100();test200();test300();
//        test400(); 无法直接访问}
}

在这里插入图片描述

在这里插入图片描述

  • 注意第6点,使用了this()后则编译器不会默认添加一个super()

在这里插入图片描述

在这里插入图片描述

4.2.4 继承的本质分析(内存分析,重要)

public class ExtendsTest{public static void main(String[] args){Son son = new son(); // 内存的布局System.out.println(son.age); // 访问父类中的属性age}
}class GrandPa{String name = "大头爷爷";String hobby = "旅游";
}class Father extends GrandPa{String name = "大头爸爸";int age = 39;
}class Son extends Father{String name = "大头儿子";
}

在这里插入图片描述

  • 执行流程:
    1. 方法区加载类信息 ,顺序由继承关系决定(Object --> GrandPa --> Father --> Son)并建立类之间的关系
    2. 在堆中创建Son的实例,按继承关系创建属性初始化(各父类中的变量会存储在独立的二级堆空间中)
    3. 将Son实例的引用赋值给main方法栈中的son引用变量
    4. 若使用son调用属性方法,则遵守以下原则:
      1. 首先看子类是否有该属性 (方法)
      2. 如果子类有这个属性 (方法),并可以访问,则返回信息
      3. 如果子类没有这个属性 (方法),就看父类有没有这个属性 (方法)(如果父类有该属性 (方法),并可以访问,就返回信息…)
      4. 如果父类没有就按照(3)的规则,继续找上级父类,直到Object。注意:如果某一父类中有该属性 (方法)但由于访问修饰符限制(如:private)无法直接访问,则java编译器会停止向其父类寻找,直接返回无法访问的编译错误

4.3 super关键字

  • 基本介绍
    注意:super不是一个对象引用,super是一个指示java编译器调用父类实例域的特殊关键字
    在这里插入图片描述

  • super的细节
    在这里插入图片描述

public class A{public void say(){System.out.println("A say~~");}
}public class B extends A{public void test(){// say();// this.say();super.say();}
}
  • 在B的方法中调用say()(与this.say()等同)的执行流程如下:
    1. 首先看子类是否有该属性 (方法)
    2. 如果子类有这个属性 (方法),并可以访问,则返回信息
    3. 如果子类没有这个属性 (方法),就看父类有没有这个属性 (方法)(如果父类有该属性 (方法),并可以访问,就返回信息…)
    4. 如果父类没有就按照(3)的规则,继续找上级父类,直到Object。注意:如果某一父类中有该属性 (方法)但由于访问修饰符限制(如:private)无法直接访问,则java编译器会停止向其父类寻找,直接返回无法访问的编译错误
      注意:使用 super.say() 会跳过上述第一步,直接从其父类开始查找

在这里插入图片描述

4.4 super与this的比较

在这里插入图片描述

4.5 方法重写/覆盖(override)

  • 基本介绍
    在这里插入图片描述

  • 方法重写注意事项和使用细节
    在这里插入图片描述

4.6 方法重写与重载比较

在这里插入图片描述

4.7 多态

4.7.1 基本介绍

在这里插入图片描述

在这里插入图片描述

注意 编译类型运行类型 的概念

4.7.2 多态注意事项和细节讨论

  • 调用方法使用运行类型,直接访问属性使用 编译类型
    在这里插入图片描述
public class Animal{public void eat(){System.out.println("...");}
}class Cat extends Animal{public void eat(){ // 方法重写System.out.println("吃鱼");        }
}class Dog extends Animal{public void eat(){ // 方法重写System.out.println("吃骨头");        }
}
public class Test{public static void main(String[] args){Animal animal = new Cat(); // 父类的引用指向了子类的实例// 可以调用父类中的所有成员(需要遵守访问权限)// 但是不能调用子类的特有的成员 (因为需要通过java的编译)// 因为在编译阶段,能调用哪些成员,是由编译类型来决定的// 最终的运行效果看子类的具体实现,即调用方法时,按照从子类开始查找方法// 然后调用,规则和我们前面讲的方法调用规则一致animal.eat(); // 调用重写的实现}
}

在这里插入图片描述

在这里插入图片描述

  • null 数据也可以使用 instanceof,其结果为 false
public class Test{public static void main(String[] args){BB bb = new BB();System.out.println(bb instanceof BB); // trueSystem.out.println(bb instanceof AA); // true// aa的编译类型是AA,运行类型是BBAA aa = new BB();System.out.println(aa.n); // "a",说明访问的是编译类型对应的属性值System.out.println(aa instanceof AA); // trueSystem.out.println(aa instanceof BB); // true,说明 instanceof 判断的是aa的运行类型是否是BB}
}class AA{String n = 'a';
}class BB extends AA{String n = 'b';
}

4.7.3 java的动态绑定机制(非常非常重要)

  1. 当调用对象 方法 的时候,该方法会和该对象的 内存地址/运行类型 绑定
  2. 当调用对象 属性 时,没有动态绑定机制,哪里声明,哪里使用
public class Test{public static void main(String[] args){A a = new B(); // 向上转型// 动态绑定机制: // (1)调用 B 类继承的sum方法(sum() 与 B 的实例绑定,这里 this --> new B()); // (2)其中getI() (同this.getI())则调用B中重写的方法; // (3)B中的getI()方法中的 i (同this.i)没有动态绑定机制则返回B的成员变量ISystem.out.println(a.sum()); // 30// 动态绑定机制: // (1)调用 B 类继承的sum1方法(sum1() 与 B 的实例绑定,这里 this --> new B()); // (3)其中的 i (同this.i)没有动态绑定机制则返回A的成员变量ISystem.out.println(a.sum1()); // 20}
}class A{ // 父类public int i = 10;public int sum(){return getI() + 10;}public int sum1(){return i + 10;}public int getI(){return i;}
}class B{ // 子类public int i = 20;public int getI(){return i;}
}

4.7.4 多态的应用

在这里插入图片描述

在这里插入图片描述

五、Object类详解

5.1 equals方法

  • Object 类的 equals 方法实现的是判断是否是同一个对象
    在这里插入图片描述

在这里插入图片描述

// 自定义equals方法
public class Person{private String name;private int age;private char gender;public Person(String name, int age, char gender){this.name = name;this.age = age;this.gender = gender;}public boolean equals(Obejct obj){if (obj == this){return true;}if(obj instanceof Person){Person pObj = (Person) obj ;return this.name.equals(pObj .name) && this.age == pObj.age && this.gender == pObj.gender;}return false;}    }

5.2 hashCode方法

在这里插入图片描述

5.3 toString()方法

在这里插入图片描述

5.4 finalize方法

在这里插入图片描述

六、断点调试

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

七、细节知识

7.1 访问修饰符

  • 成员变量方法可以被:publicprotected默认private修饰
  • 类只能被:public默认修饰
    在这里插入图片描述

注:上述多个访问范围之间是或的关系(如:protected修饰的属性或方法可以被 同类同包子类 访问)。另外 同包 指的是 完全相同的包路径(子包路径不算相同)

7.2 继承的细节

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • 注意第6点,使用了this()后则编译器不会默认添加一个super()

在这里插入图片描述

7.3 继承的本质分析(内存分析,重要)

public class ExtendsTest{public static void main(String[] args){Son son = new son(); // 内存的布局}
}class GrandPa{String name = "大头爷爷";String hobby = "旅游";
}class Father extends GrandPa{String name = "大头爸爸";int age = 39;
}class Son extends Father{String name = "大头儿子";
}

在这里插入图片描述

  • 执行流程:
    1. 方法区加载类信息 ,顺序由继承关系决定(Object --> GrandPa --> Father --> Son)并建立类之间的关系
    2. 在堆中创建Son的实例,按继承关系创建属性初始化(各父类中的变量会存储在独立的二级堆空间中)
    3. 将Son实例的引用赋值给main方法栈中的son引用变量
    4. 若使用son调用属性方法,则遵守以下原则:
      1. 首先看子类是否有该属性 (方法)
      2. 如果子类有这个属性 (方法),并可以访问,则返回信息
      3. 如果子类没有这个属性 (方法),就看父类有没有这个属性 (方法)(如果父类有该属性 (方法),并可以访问,就返回信息…)
      4. 如果父类没有就按照(3)的规则,继续找上级父类,直到Object。注意:如果某一父类中有该属性 (方法)但由于访问修饰符限制(如:private)无法直接访问,则java编译器会停止向其父类寻找,直接返回无法访问的编译错误

7.4 super细节

注意:super不是一个对象引用(不能赋值给引用变量),super是一个指示java编译器调用父类实例域的特殊关键字
在这里插入图片描述

public class A{public void say(){System.out.println("A say~~");}
}public class B extends A{public void test(){// say();// this.say();super.say();}
}
  • 在B的方法中调用say()(与this.say()等同)的执行流程如下:
    1. 首先看子类是否有该属性 (方法)
    2. 如果子类有这个属性 (方法),并可以访问,则返回信息
    3. 如果子类没有这个属性 (方法),就看父类有没有这个属性 (方法)(如果父类有该属性 (方法),并可以访问,就返回信息…)
    4. 如果父类没有就按照(3)的规则,继续找上级父类,直到Object。注意:如果某一父类中有该属性 (方法)但由于访问修饰符限制(如:private)无法直接访问,则java编译器会停止向其父类寻找,直接返回无法访问的编译错误
      注意:使用 super.say() 会跳过上述第一步,直接从其父类开始查找
      在这里插入图片描述

7.5 方法重写的细节

在这里插入图片描述

7.6 多态的理解

  • 注意 编译类型运行类型 的概念
  • 调用方法使用运行类型,直接访问属性使用 编译类型
    在这里插入图片描述

在这里插入图片描述

public class Animal{public void eat(){System.out.println("...");}
}class Cat extends Animal{public void eat(){ // 方法重写System.out.println("吃鱼");        }
}class Dog extends Animal{public void eat(){ // 方法重写System.out.println("吃骨头");        }
}
public class Test{public static void main(String[] args){Animal animal = new Cat(); // 父类的引用指向了子类的实例// 可以调用父类中的所有成员(需要遵守访问权限)// 但是不能调用子类的特有的成员 (因为需要通过java的编译)// 因为在编译阶段,能调用哪些成员,是由编译类型来决定的// 最终的运行效果看子类的具体实现,即调用方法时,按照从子类开始查找方法// 然后调用,规则和我们前面讲的方法调用规则一致animal.eat(); // 调用重写的实现}
}

在这里插入图片描述

在这里插入图片描述

public class Test{public static void main(String[] args){BB bb = new BB();System.out.println(bb instanceof BB); // trueSystem.out.println(bb instanceof AA); // true// aa的编译类型是AA,运行类型是BBAA aa = new BB();System.out.println(aa.n); // "a",说明访问的是编译类型对应的属性值System.out.println(aa instanceof AA); // trueSystem.out.println(aa instanceof BB); // true,说明 instanceof 判断的是aa的运行类型是否是BB}
}class AA{String n = 'a';
}class BB extends AA{String n = 'b';
}

7.7 java的动态绑定机制(非常非常重要)

  1. 当调用对象 方法 的时候,该方法会和该对象的 内存地址/运行类型 绑定
  2. 当调用对象 属性 时,没有动态绑定机制,哪里声明,哪里使用
public class Test{public static void main(String[] args){A a = new B(); // 向上转型// 动态绑定机制: // (1)调用 B 类继承的sum方法(sum() 与 B 的实例绑定,这里 this --> new B()); // (2)其中getI() (同this.getI())则调用B中重写的方法; // (3)B中的getI()方法中的 i (同this.i)没有动态绑定机制则返回B的成员变量ISystem.out.println(a.sum()); // 30// 动态绑定机制: // (1)调用 B 类继承的sum1方法(sum1() 与 B 的实例绑定,这里 this --> new B()); // (3)其中的 i (同this.i)没有动态绑定机制则返回A的成员变量ISystem.out.println(a.sum1()); // 20}
}class A{ // 父类public int i = 10;public int sum(){return getI() + 10;}public int sum1(){return i + 10;}public int getI(){return i;}
}class B{ // 子类public int i = 20;public int getI(){return i;}
}

这篇关于七、面向对象编程(中级)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1111317

相关文章

如何掌握面向对象编程的四大特性、Lambda 表达式及 I/O 流:全面指南

这里写目录标题 OOP语言的四大特性lambda输入/输出流(I/O流) OOP语言的四大特性 面向对象编程(OOP)是一种编程范式,它通过使用“对象”来组织代码。OOP 的四大特性是封装、继承、多态和抽象。这些特性帮助程序员更好地管理复杂的代码,使程序更易于理解和维护。 类-》实体的抽象类型 实体(属性,行为) -》 ADT(abstract data type) 属性-》成

Java基础回顾系列-第二天-面向对象编程

面向对象编程 Java类核心开发结构面向对象封装继承多态 抽象类abstract接口interface抽象类与接口的区别深入分析类与对象内存分析 继承extends重写(Override)与重载(Overload)重写(Override)重载(Overload)重写与重载之间的区别总结 this关键字static关键字static变量static方法static代码块 代码块String类特

Python中的私有属性与方法:解锁面向对象编程的秘密

在Python的广阔世界里,面向对象编程(OOP)是一种强大而灵活的方法论,它帮助我们更好地组织代码、管理状态,并构建可复用的软件组件。而在这个框架内,私有属性与方法则是实现封装的关键机制之一。它们不仅有助于隐藏类内部的具体实现细节,还能保护数据免受外部干扰。今天,让我们一起探索Python中私有属性与方法的魅力所在,了解它们如何在实际开发中发挥重要作用。 引言 随着软件系统变得越来越复杂,维

面向对象编程 和 面向过程编程 介绍

面向对象编程(Object-Oriented Programming,OOP)和面向过程编程(Procedural Programming,PP)是两种常见的编程范式。它们各自有不同的设计理念、代码组织方式和适用场景。以下是对这两种编程范式的详细介绍。 1. 面向对象编程(OOP) 面向对象编程是一种以对象为核心的编程范式,它将程序结构化为一组对象,这些对象具有特定的属性(数据)和行为(方法)

ManyToMany(基于注解)使用之进阶(中级版)

社团和成员就是多对多的关系,一个成员有多个社团,一个社团也有多个成员,这里的多对多映射采用中间表连接的映射策略,建立中间表的映射策略,建立中间表分别引入俩边的主键作为外键。通过中间表映射俩个表之间的关系。 下面就以社团类和成员类为例介绍多对多的映射关系的实例 Club实体类 package com.cn.entity;import java.io.Serializable;import j

从二叉树看类,对象和面向对象编程

一句话 对象就是活的类 对象在函数里面活动执行任务 本身的自带属性或者行为是在类里面提前定义好的 二叉树来看: 实际上,递归函数里面的root就是类的活体,本来这个类就是一个节点的类里面有三个属性,root就是类的活体,是root赋予类生命,让root能在递归函数里面成为能够动态执行函数的节点,如果没有root,类就是死的,只是一个设计图,所以可以任意调用类里面的属性 所以二叉树递归函数里面的

《C++中的面向对象编程三大特性:封装、继承与多态》

在 C++编程的广阔世界中,面向对象编程(Object-Oriented Programming,OOP)的三大特性——封装、继承和多态,犹如三把强大的利器,帮助程序员构建出高效、可维护和可扩展的软件系统。本文将深入探讨如何在 C++中实现这三大特性,并通过具体的代码示例展示它们的强大之处。 一、封装(Encapsulation) 封装是将数据和操作数据的方法封装在一个类中,以实现信息隐藏和数

php面向对象编程之--封装

php面向对象编程的三大特征 ①、封装 ②、继承 ③、多态 抽象:我们在前面研究类时,实际上是把一类事物的共有的属性和行为提取出来,形成一个物理模型。这种研究问题的方法称为抽象。 封装:  封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。 上面的操作是靠以下访问控制符号来实现,规定了自身权限,使有的人能访问,有的人不能访

【生成模型系列(中级)】词向量维度选择的奥秘——从理论到实验的揭秘【通俗理解,代码模拟】

【通俗理解】词向量维度选择的奥秘——从理论到实验的揭秘 关键词提炼 #词向量 #维度选择 #最小熵原理 #Johnson-Lindenstrauss引理 #注意力机制 #图网络 第一节:词向量维度选择的类比与核心概念【尽可能通俗】 1.1 词向量维度选择的类比 词向量维度选择就像为一场复杂的烤肉方子挑选合适的食材和分量。 每个词就像是烤肉中的不同食材,而维度就像是每种食材所需的分量。

12 Python面向对象编程:运算符重载

本篇是 Python 系列教程第 12 篇,更多内容敬请访问我的 Python 合集 在理解运算符重载之前我们已经知道了什么是方法重载,方法重载就是子类继承父类并且定义了一个和父类一样的方法。 知道了什么是重载,也知道了什么是运算符(加减乘除等),那么运算符重载也很好理解了,其实就是在类里面也定义一些特殊方法,使得调用这些方法能实现类对象的加减乘除。当然方法名不是随意取的,要和运算符对应