简介
👨💻个人主页:@云边牧风
👨🎓小编介绍:欢迎来到云边牧风破烂的小星球🌝
📋专栏:Java基础知识
🔑本章内容:Java继承与多态 之 多态性、abstract 类和abstract方法、super关键字
记得 评论📝 +点赞👍 +收藏😽 +关注💞哦~
接着第三章Java基础进阶的学习,这一章的内容主要有👇:
3.1 类的继承(√)
3.2 对象的上转型对象(√)
3.3 多态性
3.4 abstract 类和abstract方法
3.5 super关键字
第1节已经完成了类的继承和对象的上传型对象的学习,第2节我们接着👇:
一、多态性
1.0首先搞明白啥是“多态”这个概念🤔
在第二章第1节我们讲到:封装、继承、多态是面向对象(OOP)的三大特性:
封装,说简单点就是合并属性和行为创建一种新的数据类型(通俗点就是把数据和对数据的操作封装在一个class里面),而继承就是建立数据类型之间的某种关系(is-a),而多态就是这种关系在实际场景的运用(看菜吃饭,把做什么和怎么做分开了)
那么来了🌹
👉多态是同一个行为具有多个不同表现形式或形态的能力。
👉多态是指:同一个接口 使用不同的实例而执行不同操作
可以理解为下图:
1.1类的多态性体现在两个方面:
– 继承的多态性 :即应用 上转型对象 调用子类覆盖的方法,从而产生不同行为
1.2继承多态性的应用:
例如:宠物都有叫声,但不同宠物叫声不同👇
class Pet
void speak ()
class Kitty
void speak (){System.out.println(“喵喵~”);
}
class Puppy
void speak (){
System.out.println(“汪汪~”);
}
执行:
Pet a = new Kitty();
a.speak();
a = new Puppy();
a.speak();
运行结果:
喵喵~
汪汪~
再看几个代码加深一下理解:
①定义一个Car的类,包含了一个方法getSpeed()
class Car{
public int getSpeed(){
return 120;
}
}
②此时求行驶时间类Timer,可以定义一个方法getTime()
class Timer{
double getTime(Car c, double len){
return len/c.getSpeed();
}
}
③执行的代码可以这么写:
class Application{
public static main(String args[]){
Car c=new Car();//声明了一个Car的对象 c
Timer timer=new Timer();//声明了一个Timer的对象 timer
double t=timer.getTime(c,300);//使用timer的getTime(方法)
System.out.println(t);
}
}
④同理,我们模仿Car继续定义Bus类
class Bus{
public int getSpeed(){
return 100;
}
}
⑤定义Bike类
class Bike{
public int getSpeed(){
return 30;
}
}
⑥相应地,Timer可以改成这样的:
class Timer{
double getTime(Car c, double len){
return len/c.getSpeed();
}
double getTime(Bus c, double len){
return len/c.getSpeed();
}
double getTime(Bike c, double len){
return len/c.getSpeed();
}
}
⑦又回到我们执行的代码,变成了这样的:
class Application{
public static main(String args[]){
Car c=new Car();//声明了一个Car的对象 c 而且这时候可以根据需求修改类
Timer timer=new Timer();//声明了一个Timer的对象 timer
double t=timer.getTime(c,300);//使用timer的getTime(方法)
System.out.println(t);
}
}
这里的 Car c=new Car(); 可以修改成
Bus bus = new Bus();或者Bike bike = new Bike();
而其他的都不需要改变
这么看可能还不是很省事,但处理的数据越来越多的时候,这样的结构优势就凸显出来了,代码能很大程度地精简、可读;而且哪个环节需要改动,就到目标板块进行修改,不需要每个代码都修改,多态性也是使Java为什么能够面向对象的原因了。
1.3上转型应用举例——数组
• 数组由 同一类型 的一连串对象或基本数据组成,并封装在同一数组名称下
方法👉 可以使用上转型方法:
– 声明一个 Object 数组 存放不同类型元素的上转型对象;– 使用某元素时,先下转型,然后再使用
可以这么理解👇:
二、abstract 类和abstract方法
2.1、抽象类
abstract class A
{ …
}
2.2、抽象类的特点:
abstract class A {
abstract int min(int x,int y);//后面不能接花括号{}/最多只能接个空的花括号
}
2.3、抽象类的应用:
例如👇
宠物都会叫,但不同宠物叫声不同,因此,我们可以将“宠物”类定义为抽象类,将“叫声”方法声明为抽象方法,这样就通知在创建“具体的宠物类”时必须给出具体的“叫声”。
abstract class Pet { //抽象类
abstract void speak (); //抽象方法
}
class Kitty{
void speak ()}
class Puppy{
void speak ()
}
创建具体的宠物类时:
class Kitty extends Pet{
void speak(){
System.out.println("喵喵~");//必须给出具体的“叫声”
}
}
class Puppy extends Pet{
void speak(){
System.out.println("汪汪~");//必须给出具体的“叫声”
}
}
2.4、抽象类与抽象方法需要注意的问题:
例如:
abstract class A {
//类中含有抽象方法,则必须将这个类声明为抽象类
abstract int add(int x,int y);//只有抽象类才能具有抽象方法
int sub(int x,int y) { //抽象类中也可以包含非抽象方法
return x-y;
}
}
class B extends A { //B继承了A
int add(int x,int y) {
return x+y;
}
}
运行的代码为
public class Main{
public static void main(String args[]) {
B b=new B();
int sum=b.add(30,20);
int sub=b.sub(30,20);
System.out.println("sum="+sum);
System.out.println("sum="+sub);
A a;
a = b;
sum=a.add(30,20);
sub=a.sub(30,20);
System.out.println("sum="+sum);
System.out.println("sum="+sub);
}
}
总代码为(复制粘贴可直接运行)👇:
abstract class A {
//类中含有抽象方法,则必须将这个类声明为抽象类
abstract int add(int x,int y);//只有抽象类才能具有抽象方法
int sub(int x,int y) { //抽象类中也可以包含非抽象方法
return x-y;
}
}
class B extends A { //B继承了A
int add(int x,int y) {
return x+y;
}
}
public class Main {
public static void main(String[] args) {
B b=new B();
int sum=b.add(30,20);
int sub=b.sub(30,20);
System.out.println("sum="+sum);
System.out.println("sum="+sub);
A a;
a = b;
sum=a.add(30,20);
sub=a.sub(30,20);
System.out.println("sum="+sum);
System.out.println("sum="+sub);
}
}
运行结果为:
why?👇
三、super关键字
super 可以理解为是指向自己超(父)类对象的一个指针,而这个超类指的是离自己最近的一个父类。
super 的三种用法:
3.1普通的直接引用
与 this 类似,super 相当于是指向当前对象的父类,这样就可以用
super.xxx
来引用父类的成员
3.2子类中的成员变量或方法与父类中的成员变量或方法同名
直接上代码👇:
class Country {
String name;
void value() {
name = "China";
}
}
class City extends Country {
String name;
void value() {
name = "Shanghai";
super.value(); //调用父类的方法
System.out.println(name);
System.out.println(super.name);
}
}
public class Main {
public static void main(String[] args) {
City c=new City();
c.value();
}
}
运行结果:
3.3引用构造函数
这个小编也不是很明白,毕竟用的不多,如果想学好super的使用(非常精通),可以看看其他博主的文章,小编这个一直没什么运用,可以跳过哈
四、本章的应用举例
用类封装手机的基本属性和功能,要求手机即可以使用移动公司的SIM卡也可以使用联通公司SIM卡(可以使用任何公司提供的SIM卡)
1.设计抽象类
设计一个抽象类SIM,该类有三个抽象方法:giveNumber()、setNumber()和giveCorpName()
2.设计手机类
设计MobileTelephone,该类有useSIM(SIM card)方法
3.各公司手机卡类
设计SIMOfChinaMobile、SIMOfChinaUnicom类
关系图为:
代码为👇:
public abstract class SIM {
public abstract void setNumber(String n);
public abstract String giveNumber();
public abstract String giveCorpName();
}
public class MobileTelephone {
SIM card;
public void useSIM(SIM card) {
this.card=card;
}
public void showMess() {
System.out.println("使用的卡是:"+card.giveCorpName()+"提供的");
System.out.println("手机号码是:"+card.giveNumber());
}
}
+
public class SIMOfChinaMobile extends SIM {
String number;
public void setNumber(String n)
{
number = n;
}
public String giveNumber() {
return number;
}
public String giveCorpName() {
return "中国移动";
}
}
public class SIMOfChinaUnicom extends SIM {
String number;
public void setNumber(String n) {
number = n;
}
public String giveNumber() {
return number;
}
public String giveCorpName() {
return "中国联通";
}
}
public class Main {
public static void main(String args[]) {
MobileTelephone telephone = new MobileTelephone ();
SIM sim=new SIMOfChinaMobile();
sim.setNumber("15888888888");
telephone.useSIM(sim);
telephone.showMess();
sim=new SIMOfChinaUnicom();
sim.setNumber("13366666666");
telephone.useSIM(sim);
telephone.showMess();
}
}
最后的代码为:
abstract class SIM {
public abstract void setNumber(String n);
public abstract String giveNumber();
public abstract String giveCorpName();
}
class MobileTelephone {
SIM card;
public void useSIM(SIM card) {
this.card=card;
}
public void showMess() {
System.out.println("使用的卡是:"+card.giveCorpName()+"提供的");
System.out.println("手机号码是:"+card.giveNumber());
}
}
class SIMOfChinaMobile extends SIM {
String number;
public void setNumber(String n)
{
number = n;
}
public String giveNumber() {
return number;
}
public String giveCorpName() {
return "中国移动";
}
}
class SIMOfChinaUnicom extends SIM {
String number;
public void setNumber(String n) {
number = n;
}
public String giveNumber() {
return number;
}
public String giveCorpName() {
return "中国联通";
}
}
public class Main {
public static void main(String[] args) {
MobileTelephone telephone = new MobileTelephone ();
SIM sim=new SIMOfChinaMobile();
sim.setNumber("15888888888");
telephone.useSIM(sim);
telephone.showMess();
sim=new SIMOfChinaUnicom();
sim.setNumber("13366666666");
telephone.useSIM(sim);
telephone.showMess();
}
}
运行结果是:
五、本章总结
√ 类的继承子类中的成员和方法
√ 对象的上转型对象通过上转型对象能访问哪些成员和方法
√ 多态性继承的多态(通过上转型对象实现)
√ abstract 类和 abstract 方法抽象类的特点及作用
√ super关键字作用及用法
练习题1:
练习题2:
对于各种几何图形,一般都有求图形的面积、周长等方法。现在有圆、矩形和三角形三种图形,要求通过类来实现求三种图形的面积。
1.问题分析
三种图形都有相同的方法,因此可以抽象出一个抽象类:图形类,该类有抽象的求面积方法。然后由该抽象类生成3个子类:圆类、矩形类、三角形类。在主类中实现求各类图形的面积。
以上两个练习题,如果小伙伴们喜欢,可以在评论区求代码❤❤❤
结束语:
以上是Jav第三章的全部内容,希望大家喜欢
下一节开始讲第四章接口与内部类
喜欢的可以点赞+关注哈 ❤