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{
    @Override
    public void show() {
        System.out.println("学生的信息为:" + getName() + "," +  getAge());
    }
}
public class Teacher extends Person{
    @Override
    public void show() {
        System.out.println("老师的信息为" + getName() + ", " + getAge());
    }
}
public class Administrator extends Person{
    @Override
    public 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);//学生的信息为:张三,18
        register(t);//老师的信息为黄道, 38
        register(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 = "狗";

    @Override
    public 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;
    @Override
    public void eat() {
        System.out.println("狗吃骨头");
    }

    public void lookHome(){
        System.out.println("狗看家");
    }
}

class Cat extends Animal{
    @Override
    public 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
        //如果不是,则不强转,结果直接是false
        if(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("猫在抓老鼠");
    }

    @Override
    public 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("狗在看家");
    }

    @Override
    public 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);
    }*/

    //想要一个方法,能接收所有的动物,包括猫,包括狗
    //方法的形参:可以写这些类的父类 Animal
    public 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){...}

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Halo个人博客Docker部署结合内网穿透为本地站点配置公网地址远程访问

文章目录 前言1. Docker部署Halo1.1 检查Docker版本如果未安装Docker可参考已安装Docker步骤&#xff1a;1.2 在Docker中部署Halo 2. Linux安装Cpolar2.1 打开服务器防火墙2.2 安装cpolar内网穿透 3. 配置Halo个人博客公网地址4. 固定Halo公网地址 前言 本文主要介绍如何在Cen…

C#学习第二节课 ,伤害计算

伤害计算 我一直好奇游戏的伤害计算是怎么计算并输出的,这第二节课利用学过的初级语法,Console.WriteLine,Console.ReadLine(),以及基础变量,int,string 和if 判断 组合,来实现打印一下伤害计算吧! 老规矩 先上结果图 代码区域 namespace hello01 {internal class Program …

望繁信科技荣膺上海市浦东新区博士后创新实践基地称号

近日&#xff0c;上海望繁信科技有限公司&#xff08;简称“望繁信科技”&#xff09;凭借在大数据流程智能领域的卓越表现&#xff0c;成功入选上海市浦东新区博士后创新实践基地。这一荣誉不仅是对望繁信科技创新能力和技术实力的高度认可&#xff0c;也标志着公司在推动产学…

EasyCVR视频汇聚平台构建远程安防监控:5大亮点解析,助力安防无死角

随着科技的飞速发展&#xff0c;远程安防监控系统已经成为现代社会中不可或缺的一部分&#xff0c;无论是在小区、公共场所还是工业领域&#xff0c;安防监控都发挥着至关重要的作用。而EasyCVR作为一款功能强大的视频监控综合管理平台&#xff0c;其在构建远程安防监控系统方面…

Qt 学习第六天:页面布局

如何设计页面&#xff1f; 有个类似沙盒模式的玩法&#xff0c;Qt Widget Designer可以更好的帮助我们设计页面 点击.ui文件进入 右上方可以看到四种常见的布局&#xff1a; 四种布局 &#xff08;一&#xff09;水平布局horizontalLayout&#xff1a;QHBoxLayout H 是 hori…

算法之工程化内容(3)—— Docker常用命令

目录 1. 配置docker镜像加速 2. 创建镜像docker-name 3. 查看正在运行的镜像 4. 拉取镜像 5. 运行镜像 6. 停止/启动指定 id 的容器 7. 删除指定 id 的镜像/容器 8. docker发布和部署 (推荐教程&#xff1a;&#x1f69a; 发布和部署 - Docker 快速入门) 1. 配置docke…

【蓝桥杯集训100题】scratch时间计算 蓝桥杯scratch比赛专项预测编程题 集训模拟练习题第26题

目录 scratch时间计算 一、题目要求 编程实现 二、案例分析 1、角色分析 2、背景分析 3、前期准备 三、解题思路 1、思路分析 2、详细过程 四、程序编写 五、考点分析 六、推荐资料 1、入门基础 2、蓝桥杯比赛 3、考级资料 4、视频课程 5、python资料 scratc…

【网络】UDP和TCP之间的差别和回显服务器

文章目录 UDP 和 TCP 之间的差别有连接/无连接可靠传输/不可靠传输面向字节流/面向数据报全双工/半双工 UDP/TCP API 的使用UDP APIDatagramSocket构造方法方法 DatagramPacket构造方法方法 回显服务器&#xff08;Echo Server&#xff09;1. 接收请求2. 根据请求计算响应3. 将…

AdMob聚合平台

Google Admob产品介绍 Google给开发者提供了3款用于流量变现的产品&#xff0c;分别是AdMob&#xff0c;通过应用内广告帮助App开发者变现&#xff1b;AdSense&#xff0c;通过网站广告帮助所有者变现&#xff1b;Google Ads Manager&#xff0c;通过全面管理和优化广告资源&a…

[ICLR-24] LRM: Large Reconstruction Model for Single Image to 3D

[pdf | proj | code] 本文首次提出大型重建模型&#xff08;Large Reconstruction Model, LRM&#xff09;&#xff0c;实现5s内对单图物体的3D重建。在128张A100&#xff08;40G&#xff09;上训练30 epochs。 LRM包含三个部分&#xff0c;具体框架如下&#xff1a; 图片编码…

亚马逊测评号生存法则:如何抵御亚马逊封号风波?

距离黑五购物狂欢节还剩99天&#xff0c;相信各位商家都在紧锣密鼓的筹备相关事宜&#xff0c;然而&#xff0c;亚马逊的封号风波再次席卷而来。那如何在这场风暴中让亚马逊矩阵测评号安全航行亦或是脱颖而出呢&#xff1f;本文将给你一个答案&#xff0c;并帮助你的亚马逊店铺…

【java计算机毕设】足浴城消费系统小程序MySQL ssm vue uniapp maven项目设计源代码 编程语言 小组课后作业 寒暑假作业

目录 1项目功能 2项目介绍 3项目地址 1项目功能 【java计算机毕设】足浴城消费系统小程序MySQL ssm vue uniapp maven项目设计源代码 编程语言 小组课后作业 寒暑假作业 2项目介绍 系统功能&#xff1a; 足浴城消费系统小程序包括管理员、用户、商家三种角色。 管理员功能&…

Transformer大模型在训练过程中所需的计算量

目录 简介计算需求参数与数据集的权衡计算成本的工程意义内存需求推理模型权重总推理内存训练模型参数优化器状态梯度激活值和批大小总训练内存分布式训练分片优化器3D 并行分片优化器 + 3D 并行参考简介 许多关于Transformer语言模型的基本且重要的信息都可以用相当简单的方式…

C++ 特殊类设计以及单例模式

目录 1 不能被拷贝 2 只能在堆上创建对象 3 只能在栈上创建对象 4 禁止在堆上创建对象 5 不能被继承的类 6 单例类 特殊类就是一些有特殊需求的类。 1 不能被拷贝 要设计一个防拷贝的类&#xff0c;C98之前我们只需要将拷贝构造以及拷贝赋值设为私有&#xff0c;同时只声明…

2024年入职/转行网络安全,该如何规划?_网络安全职业规划

前言 前段时间&#xff0c;知名机构麦可思研究院发布了 《2022年中国本科生就业报告》&#xff0c;其中详细列出近五年的本科绿牌专业&#xff0c;其中&#xff0c;信息安全位列第一。 网络安全前景 对于网络安全的发展与就业前景&#xff0c;想必无需我多言&#xff0c;作为…

探索802.1X:构筑安全网络的认证之盾

在现代网络安全的世界里&#xff0c;有一个极其重要但又常常被忽视的角色&#xff0c;它就是802.1x认证协议。这个协议可以被称作网络安全的守护者&#xff0c;为我们提供了强有力的防护。今天&#xff0c;我们就来深入探讨一下802.1x的原理、应用和测试&#xff0c;看看它是如…

干货|光伏开发全流程

在当今全球能源转型与应对气候变化的背景下&#xff0c;光伏产业作为可再生能源的重要组成部分&#xff0c;正以前所未有的速度发展。光伏开发&#xff0c;即从项目规划到并网发电的全过程&#xff0c;涉及多个环节&#xff0c;每个步骤都至关重要。而其中户用和工商业光伏开发…

DBAPI如何用SQL将多表关联查询出树状结构数据(嵌套JSON格式)

场景描述 假设数据库中有3张表如下&#xff1a; 客户信息表 订单表 订单详情表 一个客户有多个订单&#xff0c;一个订单包含多个产品信息&#xff0c;客户-订单-产品就构成了3级的树状结构&#xff0c;如何查询出如下树状结构数据呢&#xff1f; [{"customer_age"…

Notion使用详解

​ ​ 您好&#xff0c;我是程序员小羊&#xff01; 前言 Notion是一款集笔记、任务管理、知识库、文档协作等多功能于一体的生产力工具。其灵活性和可定制性使得它在个人和团队协作中都非常受欢迎。本教程将详细介绍如何使用Notion的基本功能&#xff0c;帮助你快速上手并充分…

【云原生】Ingress控制器超级详解

Ingress资源对象 文章目录 Ingress资源对象一、Ingress1.1、Ingress是什么&#xff1f;1.2、Ingress术语1.3、Ingress类型 二、Ingress详细2.1、部署Nginx-Ingress控制器2.2、最小Ingress资源2.3、Ingress规则 三、一个域名多个访问路径多SVC四、多域名Ingress五、转发到默认Se…