Java巅峰之路---进阶篇---面向对象(二)

Java巅峰之路---进阶篇---面向对象(二)

  • 多态
    • 介绍
    • 多态调用成员的特点
    • 多态的优势、弊端以及解决方案
    • 综合练习
  • 包和final
    • 包的介绍
    • 使用其他类的规则(导包)
    • final关键字
      • final的用途
      • 常量
  • 权限修饰符和代码块
    • 权限修饰符的介绍
    • 四个权限修饰符的作用范围
    • 三种构造代码块

多态

介绍

什么是多态?
对象的多种形式。

多态的表现形式
父类类型 对象名称 = 子类对象;(Fu f = new Zi())

多态的前提?
● 有继承/实现关系
● 有父类引用指向子类对象
● 有方法的重写

多态的使用场景
不同的对象类别(学生、老师、管理者)要使用一个方法(注册)

多态的好处?
使用父类型作为参数,可以接收所有子类对象,体现多态的扩展性与便利。

演示demo
父类:

public class Person {private String name;private int age;public Person(String name, int age) {this.name = name;this.age = age;}public Person() {}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 void show(){System.out.println(name + ", " + age);}
}

所有子类:

public class Student extends Person{@Overridepublic void show() {System.out.println("学生的信息为:" + getName() + "," +  getAge());}
}
public class Teacher extends Person{@Overridepublic void show() {System.out.println("老师的信息为" + getName() + ", " + getAge());}
}
public class Administrator extends Person{@Overridepublic void show() {System.out.println("管理员的信息为:" + getName() + getAge());}
}

测试类:

public class Text {public static void main(String[] args) {Student s = new Student();s.setName("张三");s.setAge(18);Teacher t = new Teacher();t.setName("黄道");t.setAge(38);Administrator a = new Administrator();a.setName("阿伟");a.setAge(26);register(s);//学生的信息为:张三,18register(t);//老师的信息为黄道, 38register(a);//管理员的信息为:阿伟26}//这个方法既能接收老师,又能接收学生,还能接收管理员//只能把参数写成这三个类的父类public static void register(Person p){p.show();}
}

多态调用成员的特点

  • 变量调用:编译看左边,运行也看左边。

  • 方法调用:编译看左边,运行看右边。

     调用成员变量:编译看左边,运行也看左边编译看左边:javac编译代码的时候,会看左边的父类中有没有这个变量,如果有,编译成功,如果没有编译失败。运行也看左边:java运行代码的时候,实际获取的就是左边父类中成员变量的值调用成员方法:编译看左边,运行看右边编译看左边:javac编译代码的时候,会看左边的父类中有没有这个方法,如果有,编译成功,如果没有编译失败。运行看右边:java运行代码的时候,实际上运行的是子类中的方法。理解:Animal a = new Dog();现在是用a去调用变量和方法的而a是Animal类型的,所以默认都会从Animal这个类中去找成员变量:在子类的对象中,会把父类的成员变量也继承下的。父:name  子:name成员方法:如果子类对方法进行了重写,那么在虚方法表中是会把父类的方法进行覆盖的。
    

演示demo:
子类与父类:

class Animal{String name = "动物";public void show(){System.out.println("Animal --- show方法");}
}class Dog extends Animal{String name = "狗";@Overridepublic void show() {System.out.println("Dog --- show方法");}}

测试类:

        //创建对象(多态方式)//Fu f = new Zi();Animal a = new Dog();System.out.println(a.name);//动物a.show();///Dog --- show方法

多态调用成员的内存图解
在这里插入图片描述

多态的优势、弊端以及解决方案

优势:

  • 在多态形式下,右边对象可以实现解耦合,便于扩展和维护

     person p = new Student();p.work();//业务发生改变时(改成老师工作:将new Student -> new Teacher就行 ),后续代码无需修改
    
  • 定义方法的时候,使用父类型作为参数,可以接收所有子类对象

弊端:
不能使用子类的独有功能。

    报错原因:当调用成员方法的时候,编译看左边,运行看右边那么在编译的时候会先检查左边的父类中有没有这个方法或成员变量,如果没有直接报错。

解决方案:
变回子类类型就可以了。

解决原因:
可以转换成真正的子类类型,从而调用子类独有功能
细节:转换的时候不能瞎转,如果转成其他类的类型,就会报错
转换的时候用instanceof关键字进行判断

演示demo:
子类与父类:

class Animal{public void eat(){System.out.println("动物在吃东西");}
}class Dog extends Animal{String name;@Overridepublic void eat() {System.out.println("狗吃骨头");}public void lookHome(){System.out.println("狗看家");}
}class Cat extends Animal{@Overridepublic void eat() {System.out.println("猫吃小鱼干");}public void catchMouse(){System.out.println("猫抓老鼠");}
}

测试类:

        //创建对象Animal a = new Dog();//编译看左边,运行看右边a.eat();//狗吃骨头//a.lookHome();报错//a.name = "a";报错//解决方案://Cat c = (Cat) a;//c.catchMouse();运行时会报错//新特性//先判断a是否为Dog类型,如果是,则强转成Dog类型,转换之后变量名为d//如果不是,则不强转,结果直接是falseif(a instanceof Dog d){d.lookHome();//狗看家}else if(a instanceof Cat c){c.catchMouse();}else{System.out.println("没有这个类型,无法转换");}}
}

综合练习

需求:

1.定义狗类属性:年龄,颜色行为:eat(String something)(something表示吃的东西)看家lookHome方法(无参数)
2.定义猫类属性:年龄,颜色行为:eat(String something)方法(something表示吃的东西)逮老鼠catchMouse方法(无参数)3.定义Person类//饲养员属性:姓名,年龄行为:keepPet(Dog dog,String something)方法功能:喂养宠物狗,something表示喂养的东西行为:keepPet(Cat cat,String something)方法功能:喂养宠物猫,something表示喂养的东西生成空参有参构造,set和get方法  
4.定义测试类(完成以下打印效果):keepPet(Dog dog,String somethind)方法打印内容如下:年龄为30岁的老王养了一只黑颜色的2岁的狗2岁的黑颜色的狗两只前腿死死的抱住骨头猛吃keepPet(Cat cat,String somethind)方法打印内容如下:年龄为25岁的老李养了一只灰颜色的3岁的猫3岁的灰颜色的猫眯着眼睛侧着头吃鱼
5.思考:		1.Dog和Cat都是Animal的子类,以上案例中针对不同的动物,定义了不同的keepPet方法,过于繁琐,能否简化,并体会简化后的好处?2.Dog和Cat虽然都是Animal的子类,但是都有其特有方法,能否想办法在keepPet中调用特有方法?

所作图:
在这里插入图片描述
代码如下:
动物类与其子类:

public class Animal {private int age;private String color;public Animal() {}public Animal(int age, String color) {this.age = age;this.color = color;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getColor() {return color;}public void setColor(String color) {this.color = color;}public void eat(String something){System.out.println("吃" + something);}
}public class Cat extends Animal{public Cat() {}public Cat(int age, String color) {super(age, color);}public void catchMouse(){System.out.println("猫在抓老鼠");}@Overridepublic void eat(String something) {System.out.println(getAge() + "岁的"+getColor()+"颜色的猫眯着眼睛侧着头吃" + something);}
}public class Dog extends Animal {public Dog() {}public Dog(int age, String color) {super(age, color);}public void lookHome() {System.out.println("狗在看家");}@Overridepublic void eat(String something) {System.out.println(getAge() + "岁的" + getColor() + "颜色的狗两只前腿死死的抱住" + something + "猛吃");}
}

Person类:

public class Person {private String name;private int age;public Person() {}public Person(String name, int age) {this.name = name;this.age = 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 void keepPet(Dog dog, String something){System.out.println("年龄为"+age+"岁的"+name+"养了一只"+dog.getColor()+"颜色的"+dog.getAge()+"岁的狗");dog.eat(something);}public void keepPet(Cat cat, String something){System.out.println("年龄为"+age+"岁的"+name+"养了一只"+cat.getColor()+"颜色的"+cat.getAge()+"岁的猫");cat.eat(something);}*///想要一个方法,能接收所有的动物,包括猫,包括狗//方法的形参:可以写这些类的父类 Animalpublic void keepPet(Animal a , String something) {if(a instanceof Dog d){System.out.println("年龄为" + age + "岁的" + name + "养了一只" + a.getColor() + "颜色的" + a.getAge() + "岁的狗");d.eat(something);}else if(a instanceof Cat c){System.out.println("年龄为" + age + "岁的" + name + "养了一只" + c.getColor() + "颜色的" + c.getAge() + "岁的猫");c.eat(something);}else{System.out.println("没有这种动物");}}
}

测试类:

public class text {public static void main(String[] args) {Person p = new Person("老王", 30);Dog d = new Dog(2,"黑");Cat c = new Cat(3,"灰");p.keepPet(c,"鱼");p.keepPet(d,"骨头");}
}

包和final

包的介绍

什么是包?

包就是文件夹。用来管理各种不同功能的java类,方便后期代码维护。

包名的格式
公司域名反写 + 包的作用,需要全部英文小写,见名知意。如:com.itheima.domain(全类名,类真正的名字)

使用其他类的规则(导包)

  • 使用同一个包中的类时,不需要导包。
  • 使用java.lang包中的类时,不需要导包。
  • 其他情况都需要导包。
  • 如果同时使用两个包中的同类名,需要全类名。(了解即可)

演示demo:

package com.itheima.test;import com.itheima.domain2.Student;public class Test {public static void main(String[] args) {//使用同一个包中的类/*Student s = new Student();s.setName("张三");s.setAge(23);System.out.println(s.getName() + ", " + s.getAge());*///使用java.lang包下的类/*  String s = "abc";System.out.println(s);*///使用其他包中的类,需要导包Student s = new Student();//(com.itheima.domain2包下的Student)//同时使用其他两个包中的同类名com.itheima.domain1.Teacher t = new com.itheima.domain1.Teacher();com.itheima.domain2.Teacher t2 = new com.itheima.domain2.Teacher();}
}

final关键字

final的用途

最终的 --> 不可被改变

  • 修饰方法–>表名该方法是最终方法,不能被重写
  • 修饰类 --> 表名该类是最终类,不能被继承(如:String类)
  • 修饰变量 --> 叫做常量,只能被赋值一次(不能不赋值)

常量

实际开发中,常量一般作为系统的配置信息,方便维护,提高可读性。

常量的命名规范:
单个单词:全部大写
多个单词:全部大写,单词之间用下划线隔开

细节:
final修饰的变量是基本类型:那么变量存储的数据值不能发生改变。
final修饰的变量是引用类型,那么变量存储的地址值不能发生改变 对象内部的可以改变。

演示demo:

    public static void main(String[] args) {final double PI = 3.14;//PI = 3;报错//创建对象final Student S = new Student("zhangsan",23);//记录的地址值不能发生改变,内部的属性值还是可以改变的//S = new Student();报错S.setName("李四");S.setAge(24);System.out.println(S.getName() + ", " + S.getAge());//李四, 24//数组final int[] ARR = {1,2,3,4,5};//ARR = new int[10];报错ARR[0] = 10;ARR[1] = 20;//遍历数组for (int i = 0; i < ARR.length; i++) {System.out.print(ARR[i]);//1020345}}

权限修饰符和代码块

权限修饰符的介绍

  • 权限修饰符:是用来控制一个成员能够被访问的范围的。
  • 可以修饰成员变量,方法,构造方法,内部类。

范围由小到大
private<空着不写/缺省/默认<protected<public

使用规则:
1、成员变量私有 2、方法公开(有特例)

四个权限修饰符的作用范围

在这里插入图片描述

理解:
private:私房钱,只能自己(本类)用
默认:一家人(本包)都能使用
protected:受保护的,其他家里的子女(其他包的子类)也能使用
public:公共的,谁都能用

三种构造代码块

局部代码块:
可以写在方法里边

在这里插入图片描述

构造代码块:
可以写在成员位置(方法外,类里边)
在这里插入图片描述

静态代码块:
格式:static{}

特点:需要通过static关键字修饰,随着类的加载而加载,并且自动触发,只执行一次

使用场景:在类加载的时候,做一些数据初始化的时候使用(例如:给学生信息管理系统加入一些初始化的user数据)

public class App{static ArrayList<User> list = new ArrayList<>();static{//添加一些用户信息list.add(new User("zhangshan","12345678","132335678924902354","11223451234");}public static void main(String[] args){...}

总结:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/406519.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

为什么需要文献综述模板和创建文献综述技巧

为什么需要文献综述模板&#xff1f; 文献综述模板可以作为特定主题的指南。如果您的时间有限&#xff0c;无法进行更多研究&#xff0c;文献综述大纲示例可以为您提供帮助&#xff0c;因为它可以为您提供您打算研究的内容的概述。 甚至各个领域的专业人士也依赖文学评论来了解…

Openstack 与 Ceph集群搭建(上): 规划与准备

文章目录 一、写在前面1. 网络架构2. 节点规划3. 软件版本4. 避坑指南 二、基础配置1. host配置2. 修改hostname名称3. 确保root账号能登录系统4. 配置NTP5. 配置免密登录 一、写在前面 近期将进行三节点的Openstack、Ceph集群混合部署&#xff0c;本人将详细记录该过程。在此…

Linux系统编程(14)UDP全双工通信和TCP半双工通信

一、UDP全双工通信 UDP通信基础&#xff1a; recvfrom函数 recvfrom 是一个用于接收数据的函数&#xff0c;&#xff0c;但 recvfrom 不仅接收数据&#xff0c;还可以获取发送数据的地址信息。 ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sock…

融资管理系统项目

系列文章目录 第一章 基础知识、数据类型学习 第二章 万年历项目 第三章 代码逻辑训练习题 第四章 方法、数组学习 第五章 图书管理系统项目 第六章 面向对象编程&#xff1a;封装、继承、多态学习 第七章 封装继承多态习题 第八章 常用类、包装类、异常处理机制学习 第九章 集…

指针的学习和理解

初级 1、指针的概念 在64位操作系统中&#xff0c;不管什么类型的指针都占8个字节 int a1; int* p&a;//p就是一个整型的指针&#xff0c;保存了a的地址2、指针和变量 int* p&a;* p100; // 等价于a100p //p&a*有两种定义&#xff1a; 定义的时候&#xff08;前…

IP报文详解

IP的作用 上一篇文章提到TCP的可靠传输机制&#xff0c;那么TCP有把数据从主机A到主机B的能力吗&#xff1f;答案是没有。而IP有这个能力&#xff0c;IP能够将数据从主机A跨网络传输到主机B的能力。那么一定能传输成功吗&#xff1f;答案肯定是否定的&#xff0c;会因为各种原…

使用 Python构建 Windows 进程管理器应用程序

在这篇博客中&#xff0c;我们将探讨如何使用 wxPython 构建一个简单的 Windows 进程管理器应用程序。这个应用程序允许用户列出当前系统上的所有进程&#xff0c;选择和终止进程&#xff0c;并将特定进程保存到文件中以供将来加载。 C:\pythoncode\new\manageprocess.py 全部…

普元EOS-数据实体运行时动态增加property

1 前言 在Java开发读取数据的时候&#xff0c;一般都采用ORM方式将数据表的字段映射到实体对象中。 数据表中有一个字段&#xff0c;实体对象就有一个字段。 但很多时候&#xff0c;我们在读取的数据和显示的数据不同&#xff0c;比如&#xff0c;读取的是部门id&#xff0c…

探索数据结构:图(一)之邻接矩阵与邻接表

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;数据结构与算法 贝蒂的主页&#xff1a;Betty’s blog 1. 图的定义 **图&#xff08;Graph&#xff09;**是数学和计算机科学中…

这周末,除非外面下钞票,否则谁也拦不住我玩《黑神话悟空》(附:两款可以玩转悟空的显卡推荐)

主播说联播 | 从“十分之三”到“悟空”,国潮有何出圈密码? 《黑神话:悟空》里的中国古建取景地,在这里! 这周末,除非外面下钞票,否则谁也拦不住我玩《黑神话悟空》(附:两款可以玩转悟空的显卡推荐) 原创 IPBrain平台君 集成电路大数据平台 2024年08月22日 17:28 …

gif图片怎么压缩大小?深度测评7款动图压缩工具(内含教程)

gif图片在社交媒体和网络上非常流行&#xff0c;深受大家喜爱&#xff0c;因为它可以呈现生动的动画效果。gif动图之所以受到欢迎&#xff0c;主要因为其出色的压缩算法&#xff0c;能有效存储多个帧&#xff0c;从而实现流畅的动画。 然而&#xff0c;大多数社交媒体平台对gi…

[数据集][目标检测]集装箱缺陷检测数据集VOC+YOLO格式4127张3类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;4127 标注数量(xml文件个数)&#xff1a;4127 标注数量(txt文件个数)&#xff1a;4127 标注…

全新分支版本!微软推出Windows 11 Canary Build 27686版

已经很久没有看到 Windows 11 全新的分支版本了&#xff0c;今天微软发布 Windows 11 Canary 新版本&#xff0c;此次版本号已经转移到 Build 27xxx&#xff0c;首发版本为 Build 27686 版。 此次更新带来了多项改进&#xff0c;包括 Windows Sandbox 沙盒功能切换到 Microsof…

关于智能编码助手【通义灵码】,开发者们这么说...

自通义灵码发布以来&#xff0c;不停地有开发者朋友为我们送上通义灵码的测评反馈。 关于通义灵码&#xff0c;开发者这样说 墨问西东 CEO 池建强&墨问研发团队 “通义灵码有一个强大的功能就是企业知识库检索增强&#xff0c;我们只需要上传团队的代码规范&#xff0c;…

[数据集][目标检测]快递包裹检测数据集VOC+YOLO格式5382张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;5382 标注数量(xml文件个数)&#xff1a;5382 标注数量(txt文件个数)&#xff1a;5382 标注…

【C语言小项目】五子棋游戏

目录 前言 一、游戏规则 1.功能分析 2.玩法分析 3.胜负判定条件 二、游戏实现思路 三、代码实现与函数封装 1.项目文件创建 2.头文件说明 3.函数封装 1&#xff09;菜单实现 2&#xff09;进度条实现 3&#xff09;main函数实现 4&#xff09;Game函数 5&#xff0…

TIM输出比较之PWM驱动LED呼吸灯应用案例

文章目录 前言一、应用案例演示二、电路接线图三、应用案例代码四、应用案例分析4.1 基本思路4.2 相关库函数介绍4.3 初始化PWM模块4.3.1 RCC开启时钟4.3.2 配置时基单元4.3.3 配置输出比较单元4.3.4 配置GPIO4.3.5 运行控制 4.4 PWM输出模块4.5 主程序 前言 提示&#xff1a;…

[数据集][目标检测]竹子甘蔗发芽缺陷检测数据集VOC+YOLO格式2953张3类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;2953 标注数量(xml文件个数)&#xff1a;2953 标注数量(txt文件个数)&#xff1a;2953 标注…

电脑录屏高清视频制作:如何选择适合的分辨率和参数

在当今数字化时代&#xff0c;无论是教学、演示还是游戏直播&#xff0c;电脑录屏已经成为了一个不可或缺的工具。然而画质往往是录屏质量的关键因素&#xff0c;许多用户在追求高清录屏体验时&#xff0c;常常面临选择1080p还是4K分辨率的困惑。本文将深入探讨如何优化电脑录屏…

SpringBoot自动配置

一、Condition条件判断功能 Condition 是在Spring 4.0 增加的条件判断功能&#xff0c;其主要作用是判断条件是否满足&#xff0c;从而决定是否初始化并向容器注入Bean对象。通过Conditional注解及其一系列的其他相关注解实现。 在Spring Boot中&#xff0c;条件匹配&#xf…