Java入门教程||Java 多态||Java 抽象类

news/2024/4/20 18:35:27/文章来源:https://blog.csdn.net/m0_69824302/article/details/130349537

Java 多态

本章主要为大家介绍java多态的概念,以及便于理解的多态简单例子。

Java 多态


多态是同一个行为具有多个不同表现形式或形态的能力。

多态性是对象多种表现形式的体现。

比如我们说"宠物"这个对象,它就有很多不同的表达或实现,比如有小猫、小狗、蜥蜴等等。那么我到宠物店说"请给我一只宠物",服务员给我小猫、小狗或者蜥蜴都可以,我们就说"宠物"这个对象就具备多态性。

接下来让我们通过实例来了解Java的多态。

简单的例子

public interface Vegetarian{}
public class Animal{}
public class Deer extends Animal implements Vegetarian{}

因为Deer类具有多重继承,所以它具有多态性。以上实例解析如下:

  • 一个 Deer IS-A(是一个) Animal
  • 一个 Deer IS-A(是一个) Vegetarian
  • 一个 Deer IS-A(是一个) Deer
  • 一个 Deer IS-A(是一个)Object

在Java中,所有的对象都具有多态性,因为任何对象都能通过IS-A测试的类型和Object类。

访问一个对象的唯一方法就是通过引用型变量。

引用型变量只能有一种类型,一旦被声明,引用型变量的类型就不能被改变了。

引用型变量不仅能够被重置为其他对象,前提是这些对象没有被声明为final。还可以引用和它类型相同的或者相兼容的对象。它可以声明为类类型或者接口类型。

当我们将引用型变量应用于Deer对象的引用时,下面的声明是合法的:

Deer d = new Deer();
Animal a = d;
Vegetarian v = d;
Object o = d;

所有的引用型变量d,a,v,o都指向堆中相同的Deer对象。


虚方法

我们将介绍在Java中,当设计类时,被重写的方法的行为怎样影响多态性。

我们已经讨论了方法的重写,也就是子类能够重写父类的方法。

当子类对象调用重写的方法时,调用的是子类的方法,而不是父类中被重写的方法。

要想调用父类中被重写的方法,则必须使用关键字super。

/* 文件名 : Employee.java */
public class Employee
{private String name;private String address;private int number;public Employee(String name, String address, int number){System.out.println("Constructing an Employee");this.name = name;this.address = address;this.number = number;}public void mailCheck(){System.out.println("Mailing a check to " + 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;}
}

假设下面的类继承Employee类:

/* 文件名 : Salary.java */
public class Salary extends Employee
{private double salary; //Annual salarypublic Salary(String name, String address, int number, doublesalary){super(name, address, number);setSalary(salary);}public void mailCheck(){System.out.println("Within mailCheck of Salary class ");System.out.println("Mailing check to " + getName()+ " with salary " + salary);}public double getSalary(){return salary;}public void setSalary(double newSalary){if(newSalary >= 0.0){salary = newSalary;}}public double computePay(){System.out.println("Computing salary pay for " + getName());return salary/52;}
}

现在我们仔细阅读下面的代码,尝试给出它的输出结果:

/* 文件名 : VirtualDemo.java */
public class VirtualDemo
{public static void main(String [] args){Salary s = new Salary("Mohd Mohtashim", "Ambehta, UP", 3, 3600.00);Employee e = new Salary("John Adams", "Boston, MA", 2, 2400.00);System.out.println("Call mailCheck using Salary reference --");s.mailCheck();System.out.println("\n Call mailCheck using Employee reference--");e.mailCheck();}
}

以上实例编译运行结果如下:

Constructing an Employee
Constructing an Employee
Call mailCheck using Salary reference --
Within mailCheck of Salary class
Mailing check to Mohd Mohtashim with salary 3600.0Call mailCheck using Employee reference--
Within mailCheck of Salary class
Mailing check to John Adams with salary 2400.0

例子中,我们实例化了两个Salary对象。一个使用Salary引用s,另一个使用Employee引用。

编译时,编译器检查到mailCheck()方法在Salary类中的声明。

在调用s.mailCheck()时,Java虚拟机(JVM)调用Salary类的mailCheck()方法。

因为e是Employee的引用,所以调用e的mailCheck()方法则有完全不同的结果。

当编译器检查e.mailCheck()方法时,编译器检查到Employee类中的mailCheck()方法。

在编译的时候,编译器使用Employee类中的mailCheck()方法验证该语句, 但是在运行的时候,Java虚拟机(JVM)调用的是Salary类中的mailCheck()方法。

该行为被称为虚拟方法调用,该方法被称为虚拟方法。

Java中所有的方法都能以这种方式表现,借此,重写的方法能在运行时调用,不管编译的时候源代码中引用变量是什么数据类型。

Java 抽象类

在 Java 面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。

抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。

由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用。也是因为这个原因,通常在设计阶段决定要不要设计抽象类。

父类包含了子类集合的常见的方法,但是由于父类本身是抽象的,所以不能使用这些方法。


抽象类

在Java语言中使用abstract class来定义抽象类。如下实例:

/* 文件名 : Employee.java */
public abstract class Employee
{private String name;private String address;private int number;public Employee(String name, String address, int number){System.out.println("Constructing an Employee");this.name = name;this.address = address;this.number = number;}public double computePay(){System.out.println("Inside Employee computePay");return 0.0;}public void mailCheck(){System.out.println("Mailing a check to " + 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;}
}

注意到该Employee类没有什么不同,尽管该类是抽象类,但是它仍然有3个成员变量,7个成员方法和1个构造方法。 现在如果你尝试如下的例子:

/* 文件名 : AbstractDemo.java */
public class AbstractDemo
{public static void main(String [] args){/* 以下是不允许的,会引发错误 */Employee e = new Employee("George W.", "Houston, TX", 43);System.out.println("\n Call mailCheck using Employee reference--");e.mailCheck();}
}

当你尝试编译AbstractDemo类时,会产生如下错误:

Employee.java:46: Employee is abstract; cannot be instantiatedEmployee e = new Employee("George W.", "Houston, TX", 43);^
1 error

继承抽象类

我们能通过一般的方法继承Employee类:

/* 文件名 : Salary.java */
public class Salary extends Employee
{private double salary; //Annual salarypublic Salary(String name, String address, int number, doublesalary){super(name, address, number);setSalary(salary);}public void mailCheck(){System.out.println("Within mailCheck of Salary class ");System.out.println("Mailing check to " + getName()+ " with salary " + salary);}public double getSalary(){return salary;}public void setSalary(double newSalary){if(newSalary >= 0.0){salary = newSalary;}}public double computePay(){System.out.println("Computing salary pay for " + getName());return salary/52;}
}

尽管我们不能实例化一个Employee类的对象,但是如果我们实例化一个Salary类对象,该对象将从Employee类继承3个成员变量和7个成员方法。

/* 文件名 : AbstractDemo.java */
public class AbstractDemo
{public static void main(String [] args){Salary s = new Salary("Mohd Mohtashim", "Ambehta, UP", 3, 3600.00);Employee e = new Salary("John Adams", "Boston, MA", 2, 2400.00);System.out.println("Call mailCheck using Salary reference --");s.mailCheck();System.out.println("\n Call mailCheck using Employee reference--");e.mailCheck();}
}

以上程序编译运行结果如下:

Constructing an Employee
Constructing an Employee
Call mailCheck using  Salary reference --
Within mailCheck of Salary class
Mailing check to Mohd Mohtashim with salary 3600.0Call mailCheck using Employee reference--
Within mailCheck of Salary class
Mailing check to John Adams with salary 2400.

抽象方法

如果你想设计这样一个类,该类包含一个特别的成员方法,该方法的具体实现由它的子类确定,那么你可以在父类中声明该方法为抽象方法。

Abstract关键字同样可以用来声明抽象方法,抽象方法只包含一个方法名,而没有方法体。

抽象方法没有定义,方法名后面直接跟一个分号,而不是花括号。

public abstract class Employee
{private String name;private String address;private int number;public abstract double computePay();//其余代码
}

声明抽象方法会造成以下两个结果:

  • 如果一个类包含抽象方法,那么该类必须是抽象类。
  • 任何子类必须重写父类的抽象方法,或者声明自身为抽象类。

继承抽象方法的子类必须重写该方法。否则,该子类也必须声明为抽象类。最终,必须有子类实现该抽象方法,否则,从最初的父类到最终的子类都不能用来实例化对象。

如果Salary类继承了Employee类,那么它必须实现computePay()方法:

/* 文件名 : Salary.java */
public class Salary extends Employee
{private double salary; // Annual salarypublic double computePay(){System.out.println("Computing salary pay for " + getName());return salary/52;}//其余代码
}

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

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

相关文章

【C++】从C语言入门C++的基础知识

C基础知识 前言1. C关键字2. 命名空间namespace命名空间的创建命名空间的使用命名空间的注意事项 3. C输入&输出4. 缺省参数概念分类全缺省参数半缺省参数 5. 函数重载概念实现C为什么能进行函数重载C和C的相互调用(可以不用看) 6. 引用概念注意事项…

【软考备战·希赛网每日一练】2023年4月24日

文章目录 一、今日成绩二、错题总结第一题第二题第三题第四题第五题 三、知识查缺 题目及解析来源:2023年04月24日软件设计师每日一练 一、今日成绩 二、错题总结 第一题 解析: 第二题 解析: DPI表示每英寸像素点的个数。 300DPI表示每英寸…

人生中最好的等待叫做来日可期,社科院与杜兰大学金融管理硕士等你惊艳岁月

有句话说:“去日不可追,来日犹可期”。过去的已经过去,不管好的、坏的都已成为我们的回忆。人生中最好的等待就是未来可期。别辜负现在的好时光,努力做想做的事。社科院与杜兰大学金融管理硕士项目等你惊艳时光。 所有出众者的背…

塔望3W消费战略全案丨品类重新定义 打造金皇品高端速食第一面

金皇品 客户:上海皇品食品有限公司 品牌:金皇品 服务:3W消费战略 品牌全案 项目背景 金皇品隶属于上海皇品食品有限公司,品牌创立于1995年。产品以原汁作为核心卖点,通过线下渠道的密集耕耘,在浙江&…

掌握这些移动测试技巧,棘手的问题也能游刃有余解决了

目录:导读 引言 一、测试的程序 二、功能测试点 三、移动端安卓环境变量 性能测试 四、实操通过USB连接到手机设备 五、adb操作命令 写在最后 引言 你是否曾经遇到过打开一个移动应用后出现各种问题,比如卡顿、闪退等? 这些问题可能会…

重塑元宇宙体验!元宇宙实时云渲染解决方案来了

元宇宙作为人工智能、云计算和数字孪生等前沿技术的结合体,近年来越发受到各大企业重视。 元宇宙的应用场景层出不穷,不仅包括营销推广场景,还有品牌活动和电商销售,能有效提升品宣和商业转化效果。 元宇宙也具有极大的建设价值…

10种黑客类型,你知道几种?

黑客一般有 10 种类型 1、白帽黑客 白帽黑客是指通过实施渗透测试,识别网络安全漏洞,为政府及组织工作并获得授权或认证的黑客。他们也确保保护免受恶意网络犯罪。他们在政府提供的规章制度下工作,这就是为什么他们被称为道德黑客或网络安全…

setup,ref,reactive

初识setup 1.理解:Vue3.0中一个新的配置项,值为一个函数。 2.setup是所有Composition API(组合API)“表演的舞台”。 3.组件中所用到的:数据、方法等等,均要配置在setup中。 4.setup函数的两种返回值: 1.若返回一个对象,则对象中的属性、…

软件测试,想找一份20k以上的工作需要掌握哪些知识?

都知道IT行业是高薪人员的聚集地,但想要成为高薪程序员却并不容易。月薪20k是测试工程师的一个门槛,想要突破就必须掌握更多的技能。 因为程序员职业发展很快,即使是相同起点的人,经过几年的工作或学习,会迅速拉开极…

[网络原理] 详解Cookie与Session

做好准备,迎接所有的成功吧 文章目录 1. Cookie的概念2. Session的概念3. Cookie与Session的关联与区别3.1 关联3.2 区别 4. Cookie与Session中的核心方法 1. Cookie的概念 Cookie是用户首次登陆网站成功之后,对应页面的服务器会返回给用户一个身份标识,被保存在用户主机的硬盘…

自动驾驶方案及相关对标

华为: 2021年4月18日,在华为智能汽车解决方案BU新品发布会上,华为智能汽车解决方案BU总裁王军表示,华为要持续加大对汽车行业的投入,今年在研发上的投资将达到10亿美元,未来每年保持30%左右增长&#xff0…

工程化:vite4+vue3里面的less预处理的mixin,when和伪元素的使用研究

本文的起因 项目的重构,之前的语法是scss,新项目选型选的less,两种基本的使用是差不多的,细节方面有很大的差异,今天拎出来重点的细说。。。 区别 *.scss *.less mixin .bg-dp(@number: 0) {

一文讲清莱迪斯 LCMXO2-4000HC-4BG256I 可编程逻辑FPGA 特性及运用领域

一文讲清lattice莱迪斯深力科 LCMXO2-4000HC-4BG256I 可编程逻辑FPGA 特性及运用领域 适用于低成本的复杂系统控制和视频接口设计开发,满足了通信、计算、工业、消费电子和医疗市场所需的系统控制和接口应用。 瞬时启动,迅速实现控制——启动时间小于1m…

AI数字人产品“世优BOTA”发布会落幕,世优科技纪智辉演讲回顾

4月20日,世优科技式发布了新一代AI数字人产品——“世优BOTA”。在会上,世优科技创始人纪智辉介绍了数字人技术、驱动形式、数字人应用、“世优BOTA”的前世今生及未来。 以下是纪智辉的演讲内容概要: 各位嘉宾、各位朋友:大家下…

【 Spring Mybatis 复杂的查询操作 】

文章目录 引言一、参数占位符 #{} 和 ${}二、SQL 注入三、like 模糊查询四、返回类型:resultType 和 resultMap五、多表查询 引言 前面我们已经学会了使用 Mybatis 进行增,删,改操作,也实现了简单的查询操作 !下面我们…

mysql主从复制搭建--待实践完善

一、什么是mysql主从复制 参考链接:MySQL主从介绍_rain_yunlx的博客-CSDN博客 Linux下搭建Mysql主从复制详细步骤(Mysql版本5.7.35)_linuxmysql主从_Direct_的博客-CSDN博客 Linux环境MySQL数据库主从复制保姆级教程_linux主从复制_小学生…

【SWAT水文模型】ArcSWAT输入准备:土地利用/土壤/气象数据

ArcSWAT输入准备:土地利用/土壤/气象数据 1 土地利用数据的处理1.1 数据下载 2 土壤库建立2.1 数据下载 3 气象数据库参考 1 土地利用数据的处理 1.1 数据下载 下载地址如下: 中科院1km土地利用数据 清华大学高精度土地利用数据 2 土壤库建立 SW…

如何将pdf图片文字转换成word 文字word图片怎么转换pdf

如今大家在工作中常常会运用到电脑来办公,电脑的运用大大提高了我们的工作效率,在带来机会的同时同样也带来了新挑战。 pdf图片怎么转换成word文档?PDF格式是一种常用的文档格式,它可以保持文档内容和格式的完整性,但是…

【UE】制作简单的山脉地形

在上一篇博客中(【UE】使用Quixel Bridge下载免费贴图),介绍了如何下载免费贴图,本篇博客介绍如何使用这些贴图制作地形贴图。 1. 创建地形 2. 用雕刻工具绘制地形 3. 新建两个材质函数,分别命名为“GrassAuto”、“R…

离散数学期末复习第一章 数理逻辑

离散数学 离散数学是研究各种各样的离散量的结构及离散量之间的关系一门学科,是计算机科学中基础理论的核心课程。 什么是连续变量? 在一定区间内可以任意取值的变量叫连续变量,其数值是连续不断的,相邻两个数值可作无限分割&a…