Java 抽象类与接口(上)

news/2024/10/24 22:09:09/

个人主页:鲤鱼王打挺-CSDN博客 

目录

💗前言: 

💯一.多态:

1.重写与重载

1.1 override 

1.2 overlord

2.向上转型 

3.动态绑定 

4.向下转型

💯二.抽象类

1.abstract 

 2.抽象方法

💯三.接口

1.interface 与 implements

2.成员变量,成员方法 

💖小结: 


 

💗前言: 

我们已经学习了类与对象(Java 类和对象详解(下)-CSDN博客),我们知道Java面向对象具有多态性,今天我们正好借此来了解一下抽象类与接口,这对多态的学习尤为重要。

💯一.多态:

学习了继承后,当我们创建父类对象使用它时,它只能实现父类方法,那么怎么实现一个方法,可以自由调用所有子类呢?作为面试中经常提及的问题,什么是多态呢?我们接着往下看。

1.重写与重载

注意该部分属于前情提要

1.1 override 

在面向对象编程中,重写(Override)是指子类提供了一个与父类同名的方法实现,并且可以有相同的方法签名(即相同的方法名、参数列表和返回类型)。重写是实现多态性的一种方式,它允许子类改变继承自父类的行为。

重写必须满足以下条件:

  1. 子类方法必须具有与父类方法相同的方法名和参数列表。
  2. 子类方法的返回类型必须与父类方法的返回类型相同,或者是其子类型(对于协变返回类型)。
  3. 子类方法不能有比父类方法更严格的访问权限,如public大于protect。
  4. 子类方法不能重写父类的private方法,因为private方法在子类中不可见
  5. 子类方法通常需要使用@Override注解来明确表示该方法是重写了父类的方法,这有助于编译器检查重写的正确性。

总结:

方法名必须相同;

参数列表必须相同;

返回值必须相同(注意:如果返回类型构成父子类关系,也算重写【协变返回类型) ;

父类方法如果被static,final,private修饰,子类不能重写方法。

java">public class Animal {public void eat(){System.out.println("吃吃吃");}
}class Cat extends Animal{public void eat(){System.out.println("猫吃吃吃");}
}

1.2 overlord

在面向对象编程中,重载(Overloading)是指在一个类中可以有多个同名的方法,只要它们的参数列表不同。这包括参数的数量、类型或者顺序不同。重载方法可以有不同的返回类型,也可以没有返回类型(例如,如果它们是void类型的)。重载的主要目的是提供相同操作的多个版本,这些版本适用于不同的参数。

重载必须满足以下条件:

  1. 方法名必须相同。
  2. 参数列表必须不同,即参数的数量、类型或顺序至少有一个不同。
  3. 返回类型可以不同,但仅返回类型不同不足以构成重载。
  4. 访问修饰符可以不同

2.向上转型 

java中要实现多态,必须要满足如下几个条件,缺一不可:

1. 必须在继承体系下

2. 子类必须要对父类中方法进行重写

3. 通过父类的引用调用重写的方法

多态体现:在代码运行时,当传递不同类对象时,会调用对应类中的方法,向上传递是通过父类引用的一种形式。

向上转型(Upcasting)是面向对象编程中的一种类型转换,指的是将子类对象的引用赋给父类类型的引用。这种转换通常是隐式的,不需要显式地进行类型转换(也就是强制类型转换),因为子类对象可以被看作是父类对象的一个特化版本。

有如下三种方法:

1.直接赋值法 

java">//直接赋值法Animal animal = new Cat("taotao");

2.利用参数传递 

java">public class Main {public static void test(Animal aminal){aminal.eat(aminal.name);}public static void main(String[] args) {//利用参数传递Cat cat = new Cat("xiaobai");test(cat);}
}

 3.返回值传递

java">public Animal test(){return new Cat("taotao");}

3.动态绑定 

动态绑定也称为 后期绑定,即在编译时,不能确定方法的行为,需等待程序运行,才能够确定具体调用那个类的方法。

java">class Parent {public void show() {System.out.println("Parent's show()");}
}class Child extends Parent {@Overridepublic void show() {System.out.println("Child's show()");}
}public class Test {public static void main(String[] args) {Parent obj = new Child(); // 向上转型obj.show(); // 动态绑定,调用的是Child类的show()方法}
}

 在这个例子中,尽管 obj 被声明为 Parent 类型,调用的 show() 方法是 Child 类中重写的方法,因为这是在运行时根据对象的实际类型决定的。通过底层可以观察到,编译好的字节码中仍调用Animal.eat(),但是运行时,调用的却是子类中的eat()。

有动态那也就有静态绑定: 也称为早期绑定,是指在编译时就确定的方法调用。静态绑定通常应用于静态方法、私有方法、以及那些没有被子类重写的方法

java">class Parent {public void show() {System.out.println("Parent's show()");}
}class Child extends Parent {// Child类没有重写show()方法
}public class Test {public static void main(String[] args) {Parent obj = new Child(); // 向上转型obj.show(); // 静态绑定,调用的是Parent类的show()方法}
}

在这个例子中,即使 obj 实际指向的是 Child 类型的对象,调用的 show() 方法是 Parent 类中的版本,因为 Child 类没有重写这个方法,所以这是在编译时就确定了的。

4.向下转型

将一个子类对象经过向上转型之后当成父类方法使用,再无法调用子类的方法,但有时候可能需要调用子类特有的方法,此时:将父类引用再还原为子类对象即可,即向下转换。

向下转型用的比较少,而且不安全,万一转换失败,运行时就会报错。

Java中为了提高向下转型的安全性,引入了 instanceof,如果该表达式为true,则可以安全转换。 为什么被认为不安全?因为如果Cat引用成 Dog就会报错。

java">public class TestAnimal {public static void main(String[] args) {Cat cat = new Cat("xaiobai");// 向上转型Animal animal = cat;animal.eat();// 编译时编译器将animal当成Animal对象处理// 而Animal类中没有bark方法,因此报错// animal.meow();//向下转型//由于向下转型通常被认为不安全//所以要使用instanceof判断是否调用该类if(animal instanceof Cat){cat = (Cat)animal;cat.meow();}}}

 大家可以将向下转型理解为一个强制类型转换的过程。

💯二.抽象类

我们在写继承时,经常遇到父类方法对整体代码可有可无,或者说并不是我们需要的效果,通常在子类实现它。Java中就定义了抽象类,父类的方法不需要具体实现。 一个类不能描述一个具体对象时,就称为抽象类。

java">abstract class shape {// 抽象类/* 抽象方法 求面积 */public abstract double getArea( );/* 抽象方法 求周长 */public abstract double getPerimeter( );
}//主类输入圆形的半径值,创建一个圆形对象,然后输出圆形的面积和周长。。
class Circle extends shape{private double radius;public Circle(double r){this.radius = r;}public  double getArea( ){return Math.pow(radius,2)*Math.PI;}public double getPerimeter( ){return 2.0*radius*Math.PI;}
}
public class Main {public static void main(String[] args) {Scanner input = new Scanner(System.in);DecimalFormat d = new DecimalFormat("#.####");// 保留4位小数double r = input.nextDouble( );shape c = new  Circle(r);System.out.println(d.format(c.getArea()));System.out.println(d.format(c.getPerimeter()));input.close();}
}

1.abstract 

 抽象类一般使用关键字abstract来修饰,这时不能通过 new 关键字 来实例化对象。

上文代码中可以看到当类内一个方法没有具体实现时,就将这个方法用abstract修饰,留到子类中实现。

 2.抽象方法

如果一个类中有抽象方法,那么该类必须是抽象类。但如果它本身就是一个抽象类,并不强制要求含有抽象方法!当然,如果一个类继承了抽象类后却不重写抽象类中的方法,可以也加上abstract,但是总要有一个子类来实现抽象方法。

抽象类中可以有构造方法,供子类创建对象时,初始化父类的成员变量 

💯三.接口

1.interface 与 implements

 在面向对象编程(OOP)中,接口(Interface)是一个抽象类型,它定义了一组方法规范,这些方法规范可以由任何类实现(implement)。接口是实现抽象化的一种方式,它允许不同的类以统一的方式被处理。接口允许不同的类以统一的方式被处理,从而实现多态性。

java">// 定义一个接口
public interface Movable {void move();
}// 实现接口的类
public class Car implements Movable {@Overridepublic void move() {System.out.println("Car is moving.");}
}// 另一个实现接口的类
public class Bicycle implements Movable {@Overridepublic void move() {System.out.println("Bicycle is moving.");}
}

接口也不能被实例化。 

2.成员变量,成员方法 

 在Java中,接口可以看成是:多个类的公共规范,是一种引用数据类型。

在接口中:成员变量默认是public static final类型,即使不写,或者写成public时也默认成public static final。

成员方法:成员方法的默认类型是:public,所以使用private时会报错,它只能被static或default修饰。

注意:启动电脑 和 关闭电脑是小编后面加的调用。

💖小结: 

接口不能直接使用,必须要有一个"实现类"来"实现"该接口,实现接口中的所有抽象方法。今天我们浅浅了解下抽象类和接口,我们下期再见!希望给小编点赞关注支持下!


http://www.ppmy.cn/news/1541675.html

相关文章

全网免费的文献调研方法以及获取外网最新论文、代码和翻译pdf论文的方法(适用于硕士、博士、科研)

1. 文献调研 学术搜索引擎(十分推荐前三个,超有用):使用 Google Scholar(https://scholar.google.com/)(https://scholar.google.com.tw/)(巨人学术搜索‬‬)、(三个都可以,镜像网站) arXiv(https://arxiv.org/)、&am…

自动驾驶喜提融资,滴滴“不甘寂寞”

文:互联网江湖 作者:刘致呈 沉寂几年的自动驾驶赛道,再度成为资本的香饽饽。 10月18日,小马智行向美国证券交易委员会(SEC)递交上市申请,拟在纳斯达克上市。美东10月21日,文远知行…

Apache Seatunnel Zeta引擎-启动脚本分析

Apache SeaTunnel Zeta引擎的集群模式启动的第一步是执行bin/seatunnel-cluster.sh脚本,所以先来学习下这个脚本。 脚本执行流程分析 脚本简要注释 #!/bin/bash # # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license a…

关于MyBatis的一些面试题

mybatis的执行流程 MyBatis 的执行流程主要包括 SQL 解析、参数绑定、执行查询/更新、结果映射等几个步骤。下面详细解释每个步骤的执行流程: 1. 加载配置文件和映射文件 加载 MyBatis 配置文件:启动时,MyBatis 通过 SqlSessionFactoryBui…

十五、【智能体】消息节点:流式与非流式输出的比较分析

想象一个我们使用电脑场景:当我们在copy一个很大的文件,电脑会显示“正在复制”,然后还有一个进度条。 在智能体中,消息节点的作用是告知用户当前任务执行到什么阶段了,起一个提示作用。 在扣子中,消息的输…

CSS学习(Grid布局和flex布局比较)

grid网格布局真香,比flex方便太多了,grid-template-columns用法 文章目录 flex布局的时候网格grid布局的时候可以修改某一列的像素可以修改某一列的宽度占比自适应屏幕分列让第一个元素长宽都占2个 flex布局的时候 最后一行不够4个的时候 最下面一行无法…

图书库存控制:Spring Boot进销存系统的应用

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统,它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等,非常…

android黑屏问题记录

近期出现了一个黑屏问题: 仪表显示,主副屏黑的 :原因背光开启太晚,导致拍照时候是黑的,太晚的原因是绘制进程出现异常导致重启延后了时间,绘制进程crash原因是hwc调用底层库卡住,需更新hwc对应的…