设计模式作业

package sdau;public class man {public static void main(String[] args) {show(new Cat());  // 以 Cat 对象调用 show 方法show(new Dog());  // 以 Dog 对象调用 show 方法Animal a = new Cat();  // 向上转型  a.eat();               // 调用的是 Cat 的 eatCat c = (Cat)a;        // 向下转型  c.work();        // 调用的是 Cat 的 work}  public static void show(Animal a)  {a.eat();  // 类型判断if (a instanceof Cat)  {  // 猫做的事情 Cat c = (Cat)a;  c.work();  } else if (a instanceof Dog) { // 狗做的事情 Dog c = (Dog)a;  c.work();  }  }  
}abstract class Animal {  abstract void eat();  
}  class Cat extends Animal {  public void eat() {  System.out.println("吃鱼");  }  public void work() {  System.out.println("抓老鼠");  }  
}  class Dog extends Animal {  public void eat() {  System.out.println("吃骨头");  }  public void work() {  System.out.println("看家");  }  
}

1.

package sdau;

public class man {

    public static void main(String[] args) {

      show(new Cat());  // Cat 对象调用 show 方法

      show(new Dog());  // Dog 对象调用 show 方法

               

      Animal a = new Cat();  // 向上转型 

      a.eat();               // 调用的是 Cat eat

      Cat c = (Cat)a;        // 向下转型 

      c.work();        // 调用的是 Cat work

  } 

           

    public static void show(Animal a)  {

      a.eat(); 

        // 类型判断

        if (a instanceof Cat)  {  // 猫做的事情

            Cat c = (Cat)a

            c.work(); 

        } else if (a instanceof Dog) { // 狗做的事情

            Dog c = (Dog)a

            c.work(); 

        } 

    } 

}

abstract class Animal { 

    abstract void eat(); 

class Cat extends Animal { 

    public void eat() { 

        System.out.println("吃鱼"); 

    } 

    public void work() { 

        System.out.println("抓老鼠"); 

    } 

class Dog extends Animal { 

    public void eat() { 

        System.out.println("吃骨头"); 

    } 

    public void work() { 

        System.out.println("看家"); 

    } 

}

这个例子是为了说明多态存在的三个必要条件:

•   继承:要有继承关系,子类继承父类;

父类Animal中有eat()抽象方法,子类Dog,Cat继承eat(),并有自己的方法work(),

•   重写:子类要重写父类的方法;

重写eat()

•   父类引用指向子类对象。

这段 Java 代码主要演示了 Java 中的向上转型和向下转型操作。向上转型是将子类对象赋值给父类引用,而向下转型则是将父类引用强制转换回子类引用。

1. 向上转型

Animal a = new Cat();  // 向上转型

含义:创建了一个 Cat 类的对象,并将其赋值给一个 Animal 类型的引用变量 a。这就是向上转型,因为 Cat 是 Animal 的子类,子类对象可以自动转换为父类类型。

特点:通过父类引用 a 只能调用 Animal 类中定义的方法,但是实际执行的是 Cat 类中重写的方法

2. 调用方法

a.eat();               // 调用的是 Cat 的 eat

含义:调用 a 引用的 eat() 方法。由于 a 实际指向的是 Cat 类的对象,并且 Cat 类可能重写了 Animal 类的 eat() 方法,所以这里调用的是 Cat 类的 eat() 方法。

3. 向下转型

Cat c = (Cat)a;        // 向下转型

含义:将 Animal 类型的引用 a 强制转换为 Cat 类型,并赋值给 Cat 类型的引用变量 c。这就是向下转型,需要使用强制类型转换运算符 (Cat)。

注意事项:向下转型是有风险的,因为只有当 a 实际指向的是 Cat 类的对象时,这种转换才是安全的。如果 a 指向的是其他 Animal 子类的对象,会抛出 ClassCastException 异常。

4. 调用子类特有的方法

c.work();

含义:调用 Cat 类特有的 work() 方法。通过向下转型,我们可以使用 Cat 类中定义的所有方法,包括 Animal 类中没有的方法。

2.

package sdau;

public class man {

       public static void main(String [] args) {

          Salary s = new Salary("员工 A", "北京", 3, 3600.00);

          Employee e = new Salary("员工 B", "上海", 2, 2400.00);

          System.out.println("使用 Salary 的引用调用 mailCheck -- ");

          s.mailCheck();

          System.out.println("\n使用 Employee 的引用调用 mailCheck--");

          e.mailCheck();

        }

    }

 class Employee {

       private String name;

       private String address;

       private int number;

       public Employee(String name, String address, int number) {

          System.out.println("Employee 构造函数");

          this.name = name;

          this.address = address;

          this.number = number;

       }

       public void mailCheck() {

          System.out.println("邮寄支票给: " + this.name

           + " " + this.address);

       }

       public String toString() {

          return name + " " + address + " " + number;

       }

       public String getName() {

          return name;

       }

       public String getAddress() {

          return address;

       }

       public void setAddress(String newAddress) {

          address = newAddress;

       }

       public int getNumber() {

         return number;

       }

    }

 class Salary extends Employee

{

   private double salary; // 全年工资

   public Salary(String name, String address, int number, double salary) {

       super(name, address, number);

       setSalary(salary);

   }

   public void mailCheck() {

       System.out.println("Salary 类的 mailCheck 方法 ");

       System.out.println("邮寄支票给:" + getName()

       + " ,工资为:" + salary);

   }

   public double getSalary() {

       return salary;

   }

   public void setSalary(double newSalary) {

       if(newSalary >= 0.0) {

          salary = newSalary;

       }

   }

   public double computePay() {

      System.out.println("计算工资,付给:" + getName());

      return salary/52;

   }

}

1. 体现了多态的基本概念:允许不同类的对象对同一消息做出不同的响应。

Employee e = new Salary("员工 B", "上海", 2, 2400.00);

e.mailCheck();

虽然变量 e 的类型是 Employee,但实际指向的是 Salary 类的对象。当调用 e.mailCheck() 时,执行的是 Salary 类中重写的 mailCheck() 方法,而不是 Employee 类中的 mailCheck() 方法,这就是多态的具体体现。

2. 方法重写的应用

方法重写是实现多态的重要手段。在这个例子中,Salary 类继承自 Employee 类,并重写了 mailCheck() 方法。

通过方法重写,Salary 类可以提供不同行为,从而实现了对同一方法的不同响应。

3. 提高代码的可扩展性和可维护性

多态可以使代码更加灵活和易于扩展。在这个例子中,如果将来需要添加一个新的员工类型,比如 Manager 类,只需要继承 Employee 类并重写 mailCheck() 方法即可,而不需要修改现有的 main() 方法。

4. 父类引用指向子类对象的优势

使用父类引用指向子类对象可以提高代码的通用性。在 main() 方法中,Employee 类型的变量可以引用 Salary 类的对象,这样可以将不同子类的对象统一处理,减少代码的冗余。

通过这种方式,可以方便地对不同类型的员工对象进行统一的操作,而不需要为每个子类单独编写处理代码。

综上所述,这个例子很好地展示了 Java 多态的基本概念、方法重写的应用以及多态在提高代码可扩展性和可维护性方面的优势,因此非常适合用于学习 Java 多态。

理解:父类引用指向子类对象的基本概念

在 Java 中,当一个类继承另一个类时,就会形成父子类关系。我们可以使用父类类型的变量来引用子类的对象,这就是 “父类引用指向子类对象”。例如代码中有:

Employee e = new Salary("员工 B", "上海", 2, 2400.00);

这里 Employee 是父类,Salary 是子类,e 是 Employee 类型的引用变量,但它指向的是一个 Salary 类的对象。

为什么要进行父类引用指向子类对象:

假设我们要对不同类型的员工对象进行某种操作,比如调用 mailCheck() 方法。如果不使用父类引用,我们可能需要为每个子类单独编写处理代码:

Salary s = new Salary("员工 A", "北京", 3, 3600.00);

s.mailCheck();

Manager m = new Manager("经理 A", "广州", 4);

m.mailCheck();

如果有很多子类,代码会变得非常冗长和重复。而使用父类引用,我们可以将不同子类的对象统一处理:

Employee[] employees = new Employee[2];

employees[0] = new Salary("员工 A", "北京", 3, 3600.00);

employees[1] = new Manager("经理 A", "广州", 4);

for (Employee emp : employees) {

    emp.mailCheck();

}

这里定义了一个 Employee 类型的数组,数组中可以存放 Salary 类、Manager 类等 Employee 子类的对象。通过一个循环,我们可以对数组中的所有对象统一调用 mailCheck() 方法,而不需要关心每个对象具体是哪个子类的实例。

3.

package sdau;

public class man{

   public static void main(String args[]){

      Animal a = new Animal(); // Animal 对象

      Animal b = new Dog(); // Dog 对象

      a.move();// 执行 Animal 类的方法

      b.move();//执行 Dog 类的方法

   }

}

class Animal{

       public void move(){

          System.out.println("动物可以移动");

       }

    }

     

    class Dog extends Animal{

       public void move(){

          System.out.println("狗可以跑和走");

       }

    }

这个例子是说明:多态的实现方式

4.

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

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

相关文章

Kaspa Wasm SDK

文章目录 1. 简要2. github地址 1. 简要 kaspa wallet SDK,在官方WASM基础上封装了应用层的方法,简便了WASM的初始化及调用。 核心功能包括如下: 账户地址生成及管理Kaspa Api 和 Kasplex Api的封装kaspa结点RPC 封装P2SH的各个场景script封…

ROS mapserver制作静态地图

ROS mapserver制作静态地图 静态地图构建 1、获取一个PNG地图,二值化 2、基于PNG地图,生成PGM地图,可以通过一些网站在线生成,例如Convertio 文件配置 1、将文件放置于/package/map路径下。 2、编写yaml文件,如下…

tree 树组件大数据卡顿问题优化

问题背景 项目中有用到树组件用来做文件目录,但是由于这个树组件的节点越来越多,导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多,导致的浏览器卡顿,这里很明显就需要用到虚拟列表的技术&…

浏览器工作原理05 [#] 渲染流程(上):HTML、CSS和JavaScript是如何变成页面的

引用 浏览器工作原理与实践 一、提出问题 在上一篇文章中我们介绍了导航相关的流程,那导航被提交后又会怎么样呢?就进入了渲染阶段。这个阶段很重要,了解其相关流程能让你“看透”页面是如何工作的,有了这些知识,你可…

DrissionPage爬虫包实战分享

一、爬虫 1.1 爬虫解释 爬虫简单的说就是模拟人的浏览器行为,简单的爬虫是request请求网页信息,然后对html数据进行解析得到自己需要的数据信息保存在本地。 1.2 爬虫的思路 # 1.发送请求 # 2.获取数据 # 3.解析数据 # 4.保存数据 1.3 爬虫工具 Dris…

android 布局小知识点 随记

1. 布局属性的命名前缀规律 与父容器相关的前缀 layout_alignParent:相对于父容器的对齐方式。 例如:layout_alignParentTop"true"(相对于父容器顶部对齐)。layout_margin:与父容器或其他控件的边距。 例如…

GeoDrive:基于三维几何信息有精确动作控制的驾驶世界模型

25年5月来自北大、理想汽车和 UC Berkeley 的论文“GeoDrive: 3D Geometry-Informed Driving World Model with Precise Action Control”。 世界模型的最新进展彻底改变动态环境模拟,使系统能够预见未来状态并评估潜在行动。在自动驾驶中,这些功能可帮…

Java高频面试之并发编程-25

hello啊,各位观众姥爷们!!!本baby今天又来报道了!哈哈哈哈哈嗝🐶 面试官:CAS都有哪些问题?如何解决? CAS 的问题及解决方案 CAS(Compare and Swap&#xff0…

从碳基羊驼到硅基LLaMA:开源大模型家族的生物隐喻与技术进化全景

在人工智能的广袤版图上,一场从生物学羊驼到数字智能体的奇妙转变正在上演。Meta推出的LLaMA(Large Language Model Meta AI)系列模型,不仅名字源自美洲驼(llama),更以其开源特性和强大性能,引领了开源大模型社区的“驼类大爆发”…

可下载旧版app屏蔽更新的app市场

软件介绍 手机用久了,app越来越臃肿,老手机卡顿成常态。这里给大家推荐个改善老手机使用体验的方法,还能帮我们卸载不需要的app。 手机现状 如今的app不断更新,看似在优化,实则内存占用越来越大,对手机性…

Python_day47

作业:对比不同卷积层热图可视化的结果 一、不同卷积层的特征特性 卷积层类型特征类型特征抽象程度对输入的依赖程度低层卷积层(如第 1 - 3 层)边缘、纹理、颜色、简单形状等基础特征低高,直接与输入像素关联中层卷积层&#xff08…

比较数据迁移后MySQL数据库和达梦数据库中的表

设计一个MySQL数据库和达梦数据库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之…

GC1808高性能24位立体声音频ADC芯片解析

1. 芯片概述 GC1808是一款24位立体声音频模数转换器(ADC),支持8kHz~96kHz采样率,集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器,适用于高保真音频采集场景。 2. 核心特性 高精度:24位分辨率&#xff0c…

Linux 文本比较与处理工具:comm、uniq、diff、patch、sort 全解析

在类 UNIX 操作系统,特别是 Linux 系统中,命令行提供了一整套强大的文本处理工具,这些工具对于文件差异对比、内容筛选、文本排序以及源代码管理尤为重要。今天,我们将结合真实示例,深入介绍并实战演示 comm、uniq、di…

6月6日day46打卡

通道注意力(SE注意力) 知识点回顾: 不同CNN层的特征图:不同通道的特征图什么是注意力:注意力家族,类似于动物园,都是不同的模块,好不好试了才知道。通道注意力:模型的定义和插入的位置通道注意力…

前端技能包

ES6 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title> </head> <body><script>// 变量定义var a1;let b5; // 现在使用let 定义变量// 对象解构let person{&quo…

大数据(1) 大数据概述

一、大数据时代 1.三次信息化浪潮 二、什么是大数据 1.四个特点 4V&#xff1a;数据量&#xff08;Volume&#xff09;大、数据类型&#xff08;Variety&#xff09;繁多、处理速度&#xff08;Velocity&#xff09;快、价值密度&#xff08;Value&#xff09;低 三、大数据…

element-plus 单选组件 el-radio,选不上,又没报错,直接复制官网也不行解决方案

在使用 Vue 框架开发项目时&#xff0c;Element UI 是常用的组件库。最近在开发中遇到了 Element 单选框组件el-radio的双向绑定问题&#xff0c;直接复制element官网上的的案例下来也是不得&#xff0c;经过调试和探索&#xff0c;终于找到了解决方案&#xff0c;特此记录分享…

使用 Amazon Q Developer CLI 快速搭建各种场景的 Flink 数据同步管道

在 AI 和大数据时代&#xff0c;企业通常需要构建各种数据同步管道。例如&#xff0c;实时数仓实现从数据库到数据仓库或者数据湖的实时复制&#xff0c;为业务部门和决策团队分析提供数据结果和见解&#xff1b;再比如&#xff0c;NoSQL 游戏玩家数据&#xff0c;需要转换为 S…

开疆智能Ethernet/IP转Modbus网关连接质量流量计配置案例

首先设置modbus从站的485参数&#xff0c;确保网关和从站的485参数保持一致。 设置完成后打开网关配置软件并新建项目 先设置网关在Ethernet一侧的IP地址以及数据转换长度。 设置网关的Modbus参数如波特率9600无校验8数据位&#xff08;无校验选8&#xff0c;有校验选9&#xf…