Java | 继承、多态、抽象类与接口

目录

一、类的继承

二、Object类

2.1 getClass()方法

2.2 toString()方法

2.3 equals()方法

三 、对象类型的转换

3.1 向上转换

3.2 向下转型

四、使用instanceof关键字判断对象类型

五、方法的重载

六、final关键字

6.1 final变量

6.2 final方法

6.3 final类

七、多态

八、抽象类与接口

8.1 抽象类

8.2 接口


一、类的继承

在Java语言中,一个类继承另一个类需要使用关键字extends,关键字extends的使用方法如下:

class Child extends Parent{}

因为Java只支持单继承,即一个类只能由一个父类,所以下面的代码是错误的:

class Child entends Parent1,Parent2{}

子类在继承父类之后,创建子类对象的同时也会调用父类的构造方法

父类Parent和子类Child都各自有一个无参数的构造方法,在main()方法中创建子类对象时,Java虚拟机会先执行父类的构造方法,然后再执行子类的构造方法。

package haha;class Parent{   	public Parent() {System.out.println("调用父类构造方法");}
}class Child extends Parent{public Child() {System.out.println("调用子类构造方法");}
}public class Demo{public static void main(String[] args) {new Child();}
}

子类继承父类之后可以调用父类创建好的属性和方法。

package haha;class Telephone{           //电话类String button="button:0~9";        //成员属性,10个按键void call() {                      //拨打电话功能System.out.println("开始拨打电话"); }
}class Mobile extends Telephone{      //手机类继承电话类String screen="screen:液晶屏";     //成员属性,液晶屏幕
}public class Demo2{public static void main(String[] args) {Mobile motto=new Mobile();System.out.println(motto.button);         //子类调用父类属性System.out.println(motto.screen);         //子类调用父类没有的属性motto.call();                             //子类调用父类方法}
}

Java虽然不允许同时继承两个父类,但不代表没有多继承的关系,可以通过类似“祖父>父>儿子>孙子”的方式实现多代继承。

class Animal{           //父类:动物类Eye eye;Mouth mouth;Nose nose;
}
class Dog extends Animal{}        //子类:犬类
class Husky extends Dog{}         //孙子类:哈士奇类

虽然Husky类没有直接继承Animal类,但是Husky可以调用Animal类提供的可被继承的成员变量和方法。

二、Object类

在Java中所有的类都直接或间接继承了java.lang.Object类。Object类是比较特殊的类,它是所有类的父类,是Java类层中最高层类。用户创建一个类时,除非已经指定要从其他类继承,否则它就是从java.lang.Object类继承而来的。由于所有的类都是Object类的子类,所以在定义时可省略extends Object。

在Object类中,主要包括clone()、finalize()、equals()、toString()等方法,其中常用的两个方法为equals()和toString()方法。由于所有的类都是Object类的子类,所以任何类都可以重写Object类中的方法

Object类中的getClass()、notify()、notifyAll()、wait()等方法不能被重写,因为这些方法被定义为final类型。

2.1 getClass()方法

getClass()方法是Object类定义的方法,它会返回对象执行时的Class实例,然后使用此实例调用getName()方法可以取得类的名称。语法如下:

getClass().getName();

可以将getClass()方法与toString()方法联合使用。

2.2 toString()方法

toString()方法的功能是将一个对象返回为字符串形式,它会返回一个String实例。在实际应用中通常重写toString()方法,为对象提供一个特定的输出模式。当这个类转换为字符串或与字符串连接时,将自动调用重写的toString()方法。

package haha;public class Student{String name;int age;public Student(String name,int age) {this.name=name;this.age=age;}public String toString() {return "我叫"+name+",今年"+age+"岁。";}public static void main(String[] args) {Student s1=new Student("张三",16);System.out.println(s1);Student s2=new Student("李四",19);System.out.println(s2);}
}

2.3 equals()方法

在Java语言中,有两种比较对象的方式,分别为“==”运算符与equals()方法。两者的区别在于:“==”比较的是两个对象引用内存地址是否相等,而equals()方法比较的是两个对象的实际内容。 

package haha;public class People{int id;             //身份证号String name;        //名字public People(int id,String name) {this.id=id;this.name=name;}public boolean equals(Object obj) {         //重写Object类的equal()方法if(this==obj)                           //如果参数与本类是同一个对象return true;if(obj==null)return false;                       //如果参数是nullif(getClass() != obj.getClass())        //如果参数与本类类型不同return false;People other=(People) obj;              //将参数强转成本类对象if(id != other.id)                      //如果两者的身份证号不相等return false;return true;}public String toString() {                  //重写object类的toString()方法return name;                            //只输出名字}public static void main(String[] args) {People p1=new People(220,"tom");People p2=new People(220,"汤姆");People p3=new People(330,"张三");Object o=new Object();System.out.println(p1+"与"+p2+"是否为同一人?");System.out.println("equal()方法的结果:"+p1.equals(p2));System.out.println("==运算符的结果:"+(p1==p2));System.out.println();System.out.print(p1+"与"+p3+"是否为同一人?");System.out.println(p1.equals(p3));System.out.print(p1+"与"+o+"是否为同一人?");System.out.println(p1.equals(o));}
}

三 、对象类型的转换

3.1 向上转换

向上转换可以理解为将子类类型的对象转换为父类类型的对象,即把子类类型的对象直接赋值给父类类型的对象,进而实现按照父类描述子类的效果。

class People {}
class Teacher extends People {}
public class Demo3{public static void main(String[] args){People tom=new Teacher();
}

进行向上转型,父类类型的对象二可以引用子类类型的对象。而且,向上转型是安全的,因为向上转型是将一个较具体的对象转换为一个较抽象的类的对象。

在运用向上转型的过程中,父类的对象无法调用子类独有的属性或者方法

3.2 向下转型

向下转型可以理解为将父类类型的对象转换为子类类型得到对象。但是,运用向下转型,如果把一个较抽象的类的对象转换为一个较具体的类的对象。这样的转型通常会出现错误。

要想实现向下转型,需要借助强制类型转换。语法如下:

子类类型 子类对象 = (子类类型)父类对象

两个没有继承关系的对象不可以进行向上转型或者向下转型。

父类对象可以强制转换为子类对象,但是有一个前提:这个父类对象要先引用这个子类对象。

Bird bird=new Peigon()      //某只鸽子是一只鸟
Pigeon pigeon=(Pigeon) bird     //通过强制类型转换,告诉编译器“某只鸟就是一只鸽子”

四、使用instanceof关键字判断对象类型

当在程序中执行向下转型操作时,如果父类对象不是子类对象的实例,就会发生ClassCastException异常,所以在执行向下转型之前需要养成一个良好的习惯,就是判断父类对象是否为子类对象的实例。这个判断通常使用instanceof关键字来完成。可以使用instanceof关键字判断是否一个类实现了某个接口,也可以用它来判断一个实例对象是否属于一个类。

instanceof的语法格式如下:

myobject instanceof ExampleClass
  • myobject:某类的对象引用。
  • ExampleClass:某个类。

使用instanceof关键字的表达式返回值为布尔值。如果返回值为true,说明myobject对象为ExampleClass的实例对象;如果返回值为false,说明myobject对象不是ExampleClass的实例对象。

instanceof是Java语言的关键字,Java语言中的关键字都为小写。

由于四边形类与圆形类没有继承关系,因此两者不能使用instanceof关键字进行比较,否则会发生“不兼容”错误。如果删除或注释掉这行代码,则:

package haha;class Quadrangle{}
class Square extends Quadrangle{}
class Circular{}public class Demo5{public static void main(String args[]) {Quadrangle q=new Quadrangle();            //四边形对象Square s=new Square();                    //正方形对象System.out.println(q instanceof Square);  //判断四边形是否为正方形的子类System.out.println(s instanceof Quadrangle);  //判断正方形是否为四边形的子类}
}

 

五、方法的重载

如果希望以不同的方式来实例化对象,就需要使用多个构造方法来完成。由于这些构造方法都需要根据类名进行命名,为了 让方法名相同而形参不同构造方法同时存在,必须用到方法重载。虽然方法重载起源于构造方法,但它也可以应用到其他方法中

方法的重载就是在同一个类中允许存在一个以上的同名方法,只要这些方法的参数个数或类型不同即可。

package haha;public class OverLoadTest{public static int add(int a,int b) {        //定义一个方法return a+b;}public static double add(double a,double b) {       //与第一个方法名称相同,参数类型不同return a+b;}public static int add(int a) {            //与第一个方法参数个数不同return a;}public static int add(int a,double b) {return a;}public static int add(double a,int b) {       return b;}public static void main(String[] args) {System.out.println("调用add(int,int)方法:"+add(1,2));System.out.println("调用add(double,double)方法:"+add(2.1,3.3));System.out.println("调用add(int)方法:"+add(1));System.out.println("调用add(int,double)方法:"+add(5,8.0));System.out.println("调用add(double,int)方法:"+add(5.0,8));}
}

在本例中分别定义了5个方法,在这5个方法中,前两个方法的参数类型不同,并且方法的返回值类型也不同,所以这两个方法构成重载关系;前两个方法与第3个方法相比,第3个方法的参数个数少于前两个方法,所以这3个方法也构成重载关系;最后两个方法相比,发现除了参数的出现顺序不同,其他都相同,同样构成重载关系。

虽然在方法重载中可以使两个方法的返回类型不同, 但只有返回类型不同并不足以区分两个方法的重载,还需要通过参数的个数以及参数的类型来设置

 编译器是利用方法名、方法各参数类型和参数的个数、参数的顺序来确定类中的方法是否唯一。

不定长方法的语法如下:

返回值 方法名(参数数据类型...参数名称)
package haha;public class OverLoadTest{public static int add(int a,int b) {        //定义一个方法return a+b;}public static double add(double a,double b) {       //与第一个方法名称相同,参数类型不同return a+b;}public static int add(int a) {            //与第一个方法参数个数不同return a;}public static int add(int a,double b) {return a;}public static int add(double a,int b) {       return b;}public static int add(int...a) {     //定义不定长方法int s=0;for(int i=0;i<a.length;i++) {s+=a[i];}return s;}public static void main(String[] args) {System.out.println("调用add(int,int)方法:"+add(1,2));System.out.println("调用add(double,double)方法:"+add(2.1,3.3));System.out.println("调用add(int)方法:"+add(1));System.out.println("调用add(int,double)方法:"+add(5,8.0));System.out.println("调用add(double,int)方法:"+add(5.0,8));//调用不定长参数方法System.out.println("调用不定长参数方法:"+add(1,2,3,4,5,6,7,8,9));System.out.println("调用不定长参数方法:"+add(1));}
}

六、final关键字

凡是被final关键字修饰过的内容都是不可改变的。

6.1 final变量

如果在程序中再次对定义为final的常量赋值,编译器将不会接受

final关键字定义的变量必须在声明时对其进行赋值操作。final除了可以修饰基本数据类型的常量,还可以修饰对象引用。由于数组也可以被看作一个对象来引用,所以final可以修饰数组。一旦一个对象引用被修饰为final后,它就只能恒定指向一个对象,无法将其改变以指向另一个对象。一个既是static又是final的字段只占据一段不能改变的存储空间

6.2 final方法

将方法定义为final类型,可以防止子类修改父类的定义与实现方式,同时定义为final的方法的执行效率要高于非final方法。

在修饰权限中曾经提到过final修饰符,如果一个父类的某个方法被设置为private,子类将无法访问该方法,自然无法覆盖该方法。也就是说,一个定义为private的方法隐式被指定为final类型。因此无须将一个定义为private的方法再定义为final类型

class Dad{public final void turnOnTheTV{System.out.println("爸爸打开了电视");}
}class Baby extends Dad{public final void trunOnTheTV{System.out.println("宝宝也要打开电视");}
}

本实例运行前会报错,因为打开电视这个方法是由final修饰,子类无法打开,所以Baby想要打开电视,就只能找爸爸打开。

6.3 final类

定义为final的类不能被继承。如果希望一个类不被继承,并且不允许其他人对这个类进行任何改动,可以将这个类设置为final类。

final 类名{}

如果将某个类设置为final类,则该类中的所有方法都被隐式设置为final方法,但是final类中的成员变量可以被定义为final或非final形式。

七、多态

package haha;class Shape{}         //图形类
class Square extends Shape{}      //正方形类继承图形类
class Circular extends Shape{}    //圆形类继承图形类public class Demo6{public static void draw(Shape s) {    //绘制方法if(s instanceof Square) {         //如果是正方形System.out.println("绘制正方形");}else if(s instanceof Circular) {    //如果是圆形System.out.println("绘制圆形");     }else {                              //如果是其他类型System.out.println("绘制父类图形");}}public static void main(String[] args) {draw(new Shape());draw(new Square());draw(new Circular());}
}

八、抽象类与接口

仅用来描述特征切极具抽象性类,在Java中被定义为抽象类。

8.1 抽象类

在Java语言中 设置抽象类不可以实例化为对象。

使用abstrct关键字定义的类称为抽象类,而使用这个关键字定义的方法称为抽象方法。抽象方法没有方法体,这个方法本身没有任何意义,除非它被重写,而承载这个抽象方法的抽象类必须被继承,实际上抽象类除了被继承没有任何意义

public abstract class Parent{abstract void testAbstract();     //定义抽象方法
}

反过来讲,如果声明一个抽象方法,就必须将承载这个抽象方法的类称为抽象类,不能在非抽象类中获取抽象方法。换句话说,只有类中有一个抽象方法,此类就被标记为抽象类。

抽象类被继承后需要实现其中所有的抽象方法,也就是保证以相同的方法名称。参数列表和返回值类型创建出非抽象方法,当然也可以是抽象方法。

继承抽象类的所有子类需要将抽象类的抽象方法进行覆盖。

Java中规定不能同时继承多个父类。

8.2 接口

接口是抽象类的延伸,可以将它看作是纯粹的抽象类,接口中的所有方法都没有方法体

接口使用interface关键字进行定义,其语法如下:

public interface Paintable{void draw();              //定义接口方法可省略public abstract
}
  • public:接口可以像类一样被权限修饰符修饰,但public关键字仅限用于接口在与其同名的文件中被定义。
  • interface:定义接口关键字。
  • Paintable:接口名称。

一个类继承一个父类的同时再实现一个接口,可以写成如下形式:

public class Parallelogram extends Quadrangle implements Paintable{...
}

在接口中,方法必须被定义为public或abstract形式,其他修饰权限不被Java编译器认可。或者说,即使不将该方法声明为public形式,它也是public形式。

在接口中定义的任何字段都自动是static和final的。

package haha;interface Paintable{               //可绘制接口public void draw();            //绘制抽象方法
}class Quadrangle{                  //四边形类public void doAnything() {System.out.println("四边形提供的方法");}
}//平行四边形类,继承四边形类,并实现了可绘制接口
class Parallelogram extends Quadrangle implements Paintable{public void draw() {                                       //由于该类实现了接口,所以需要覆盖draw()方法System.out.println("绘制平行四边形");}
}//正方形类,继承四边形类,并实现了可绘制接口
class Square extends Quadrangle implements Paintable{public void draw() {System.out.println("绘制四边形");}
}//圆形类,仅实现可绘制接口
class Circular implements Paintable{public void draw() {System.out.println("绘制圆形");}
}public class Demo7{public static void main(String[] args) {Square s=new Square();s.draw();s.doAnything();Parallelogram p=new Parallelogram();p.draw();p.doAnything();Circular c=new Circular();c.draw();}
}

Java中不允许出现多重继承,但使用接口就可以实现多重继承。一个类可以同时实现多个接口,因此可以将所有需要继承的接口放置在implements关键字后并使用逗号隔开。实现多个接口的语法如下:

class 类名 implements 接口1,接口2,...,接口n

但这可能会在一个类中产生庞大的代码量,因为继承一个接口时需要实现接口中的所有方法。一个接口可以继承另一个接口,其语法如下:

interface intf1 {}
interface intf2 extends intf1 {}  //接口继承接口

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

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

相关文章

【多模态】19、RegionCLIP | 基于 Region 来实现视觉语言模型预训练

文章目录 一、背景二、方法2.1 Region-based Language-Image Pretraining2.2 目标检测的迁移学习 三、效果3.1 数据集3.2 实现细节3.3 结果 论文&#xff1a; RegionCLIP: Region-based Language-Image Pretraining 代码&#xff1a;https://github.com/microsoft/RegionCLIP …

了解Unity编辑器之组件篇Playables和Rendering(十)

Playables 一、Playable Director&#xff1a;是一种用于控制和管理剧情、动画和音频的工具。它作为一个中央控制器&#xff0c;可以管理播放动画剧情、视频剧情和音频剧情&#xff0c;以及它们之间的时间、顺序和交互。 Playable Director组件具有以下作用&#xff1a; 剧情控…

Vue中使用echarts

1 安装 npm install -g cnpm --registryhttps://registry.npm.taobao.org cnpm install echarts -S 2 main.js引入 3 引入成功

探索Java API学习路线:从基础到高级的全面指南

文章目录 第一阶段&#xff1a;入门基础1. 环境准备2. 学习Java基础 第二阶段&#xff1a;熟悉常用的Java API1. Java标准库2. Java API文档 第三阶段&#xff1a;深入学习特定领域的Java API1. Java GUI API2. Java数据库连接&#xff08;JDBC&#xff09;API3. Java多线程API…

【蓝图】p44简单解密机关

p44简单解密机关 p44简单解密机关文字提示开门文字提示开灯For Each Loop和For Each Loop With Break区别For Each LoopFor Each Loop With Break小操作&#xff1a;改变走线Execute Console Command(执行控制台命令) p44简单解密机关 文字提示开门 创建Actor蓝图类&#xff…

Python及PyCharm安装教程

1.Python安装教程 python官网下载windows64位python installer&#xff1b; 这里选择windows installer(64-bit) 打开下载完成的installer文件 记得勾选上Add python.exe to PATH&#xff0c;再点击Install Now&#xff1b; &#xff08;如果想要更改安装位置&#xff0c;需要…

【使用时空RBF-NN进行非线性系统识别】实现了 RBF、分数 RBF 和时空 RBF 神经网络,用于非线性系统识别研究(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 2.1 算例1 2.2 算例2 &#x1f389;3 参考文献 &#x1f308;4 Matlab代码实现 &#x1f4a5;1 概述 本文用于非线性系统识别任务的径向基函数神经网络&#xff08;RBF-NN&#xff09;的三种变体。特别是&#xff0c;我实现…

redis到底几个线程?

通常我们说redis是单线程指的是从接收客户端请求->解析请求->读写->响应客户端这整个过程是由一个线程来完成的。这并不意味着redis在任何场景、任何版本下都只有一个线程 为何用单线程处理数据读写&#xff1f; 内存数据储存已经很快了 redis相比于mysql等数据库是…

宋浩高等数学笔记(八)向量代数与空间解析几何

本章知识点并不难理解&#xff0c;但是公式与名词属于非常多&#xff0c;记忆时需重点对待。

lc154.寻找旋转排序数组中的最小值

最小元素的位置以旋转次数为索引的位置&#xff0c;但是没有告诉旋转次数&#xff0c;换一种思路 当遇到arr[index] > arr[index1]时&#xff0c;index1为最小元素的位置。首位位置独立比较。但是这种方法还是遍历数组 观察两组数的中间值与首尾的值&#xff0c;又由于数组…

vue动态引入静态资源

vue动态引入静态资源 静态资源位置&#xff08;../../assets/piecture/page404.jpg&#xff09;或者&#xff08;/assets/piecture/page404.jpg&#xff09; 错误引入方式 错误引入方式&#xff08;一&#xff09; <template><div><img :src"../../asset…

视频剪辑矩阵分发系统Unable to load FFProbe报错技术处理?

问题一 报错处理 对于视频剪辑矩阵分发系统中出现的“Unable to load FFProbe”报错问题&#xff0c;可以采取以下技术处理措施进行解决。 1.检查系统中是否正确安装了FFProbe工具&#xff0c;并确保其路径正确配置。 2.检查系统环境变量是否正确设置&#xff0c;包括FFPr…

【安全】web中的常见编码浅析浏览器解析机制

目录 常见编码 一、ASCII码 二、URL编码 三、Unicode编码 四、HTML实体编码 结合编码理解浏览器解析机制 常见编码 一、ASCII码 ASCII (American Standard Code for Information Interchange&#xff0c;美国信息交换标准代码&#xff09; 计算机内部&#xff0…

《MySQL》第十二篇 数据类型

目录 一. 整数类型二. 浮点类型三. 日期和时间类型四. 字符串类型五. 枚举值类型六. 二进制类型七. 小结 MySQL 支持多种数据类型&#xff0c;学习好数据类型&#xff0c;才能更好的学习 MySQL 表的设计&#xff0c;让表的设计更加合理。 一. 整数类型 类型大小SIGNED(有符号)…

Redis - 三大缓存问题(穿透、击穿、雪崩)

缓存穿透 概念&#xff1a; 查询一个数据库中也不存在的数据&#xff0c;数据库查询不到数据也就不会写入缓存&#xff0c;就会导致一直查询数据库 解决方法&#xff1a; 1. 缓存空数据 如果数据库也查询不到&#xff0c;就把空结果进行缓存 缺点是 - 消耗内存 2. 使用布…

【HMS Core】统一扫描连续扫码、闪光灯关闭问题

【问题描述1】 使用Default View Mode进行扫码&#xff0c;如何实现连续扫码 【解决方案】 在默认扫码模式Default View中&#xff0c;功能是集成在SDK内部的&#xff0c;无法设置连续扫码模式等信息。 可以使用Customized View Mode这种模式&#xff0c;它提供了相关的api可…

【软件测试】什么是selenium

1.seleniumJava环境搭建 前置条件: Java最低版本要求为8,浏览器使用chrome浏览器 1.1下载chrome浏览器 https://www.google.cn/chrome/ 1.2查看浏览器版本 点击关于Google chrome. 记住版本的前三个数. 1.3下载浏览器驱动 http://chromedriver.chromium.org/downloads 下载…

CSS鼠标样式(cursor)

CSS cursor 属性值 属性值示意图描述auto默认值&#xff0c;由浏览器根据当前上下文确定要显示的光标样式default 默认光标&#xff0c;不考虑上下文&#xff0c;通常是一个箭头none不显示光标initial将此属性设置为其默认值inherit从父元素基础 cursor 属性的值context-menu…

微信小程序中使用echarts方法

小程序中使用echarts echarts是一个基于JS的数据可视化图标库&#xff0c;它提供了直观&#xff0c;生动&#xff0c;可交互&#xff0c;可个性定制的数据可视化图表。一般在vue中会使用到&#xff0c;并且官网也详细的说明了如何在vue中使用&#xff0c;但是今天我想来探讨的…

vue-echarts配置项详解

起因 最近接手了一个vue3项目&#xff0c;echarts用的是"vue-echarts": “^6.0.0”&#xff0c;每次查看文档的时候痛苦不已&#xff0c;找一个配置要花费大量时间&#xff0c;所以这篇文章&#xff0c;主要就是为了记录比较常见的一些配置。 主要会写三种图的配置…