【Java基础】-【多态与接口】

一、多态

1.多态概述

某一个事物,在不同时刻表现出来的不同状态。
举例:

	//猫可以是猫的类型。
	猫 m = new 猫();
	//同时猫也是动物的一种,也可以把猫称为动物。
	动物 d = new 猫();

2.多态前提

①要有继承关系
②要有方法重写[没有则没有意义 ]
③要有父类引用指向子类对象

	父 f = new 子();

3.多态访问成员变量

成员变量
-编译看左边,运行看左边
②构造方法
-创建子类对象时,访问父类的构造方法,对父类的数据进行初始化。
成员方法
-编译看左边,运行看右边
④静态方法
-编译看左边,运行看左边
多态继承中的内存图解
多态继承中的内存图解

4.多态的优势和弊端

优势
①提高了代码的维护性(继承)。
②提高了代码的扩展性。
弊端
不能访问子类特有功能。

5.对象间的转型

向上转型
从子到父.父类引用指向子类对象

Fu f = new Zi();

向下转型
从父到子.父类引用转为子类对象

Zi z = (Zi)f;

转型理解实例:

class 孔子爹 
{
	public int age = 40;
	
	public void teach() {
		System.out.println("讲解JavaSE");
	}
}

class 孔子 extends 孔子爹 
{
	public int age = 20;
	
	public void teach() {
		System.out.println("讲解论语");
	}
	
	public void playGame() {
		System.out.println("英雄联盟");
	}
}

//Java培训特别火,很多人来请孔子爹去讲课,这一天孔子爹被请走了
//但是还有人来请,就剩孔子在家,价格还挺高。孔子一想,我是不是可以考虑去呢?
//然后就穿上爹的衣服,带上爹的眼睛,粘上爹的胡子。就开始装爹
//向上转型
孔子爹 k爹 = new 孔子();
//到人家那里去了
System.out.println(k爹.age); //40
k爹.teach(); //讲解论语
//k爹.playGame(); //这是儿子才能做的	

//讲完了,下班回家了
//脱下爹的装备,换上自己的装备
//向下转型
孔子 k = (孔子) k爹; 
System.out.println(k.age); //20
k.teach(); //讲解论语
k.playGame(); //英雄联盟

多态中的对象变化内存图解
多态中的对象变化内存图解
思考题

思考1:
看程序写结果:先判断有没有问题,如果没有,写出结果
class A {
	public void show() {
		show2();
	}
	public void show2() {
		System.out.println("我");
	}
}
class B extends A {
	/*
	public void show() {
		show2();
	}
	*/

	public void show2() {
		System.out.println("爱");
	}
}
class C extends B {
	public void show() {
		super.show();
	}
	public void show2() {
		System.out.println("你");
	}
}
public class DuoTaiTest {
	public static void main(String[] args) {
		A a = new B();
		a.show();
		
		B b = new C();
		b.show();
	}
}

答:
输出 “爱你”
多态的成员访问特点:
-方法:编译看左边,运行看右边。
继承的时候:
-子类中有和父类中一样的方法,叫重写。
-子类中没有父亲中出现过的方法,方法就被继承过来了。

二、抽象类

1.抽象类概述

在Java中,一个没有方法体的方法应该定义为抽象方法,而类中如果有抽象方法,该类必须定义为抽象类。

2.抽象类特点

①抽象类和抽象方法必须用abstract关键字修饰。
②抽象类中不一定有抽象方法,但是有抽象方法的类必须定义为抽象类。
③ 抽象类不能实例化
-抽象类有构造方法,但是不能实例化,用于子类访问父类数据的初始化。

//抽象类的实例化其实是靠具体的子类实现的。是多态的方式。
Animal a = new Cat();

④抽象的子类
-如果不想重写抽象方法,该子类是一个抽象类。
-重写所有的抽象方法,这个时候子类是一个具体的类。

3.抽象类的成员特点

-成员变量:既可以是变量,也可以是常量。
-构造方法:有,用于子类访问父类数据的初始化。
-成员方法:既可以是抽象的,也可以是非抽象的。
抽象类的成员方法特性:
A:抽象方法 强制要求子类做的事情。
B:非抽象方法 子类继承的事情,提高代码复用性。
思考题

思考1:	
一个类如果没有抽象方法,可不可以定义为抽象类?
如果可以,有什么意义?

答:可以,不让创建对象。
—————————————————————————

思考2:
abstract不能和哪些关键字共存?

答:private-冲突、final-冲突、static-无意义。
—————————————————————————

三、接口

1.接口概述

为了体现事物功能的扩展性,Java中就提供了接口来定义这些额外功能,并不给出具体实现。

2.接口特点

①接口用关键字interface表示

格式:interface 接口名 {}

②类实现接口用implements表示

格式:class 类名 implements 接口名 {}

③接口不能实例化
按照多态的方式来实例化。
多态的几种方式:
-具体类多态(几乎没有)
-抽象类多态(常用)
-接口多态(最常用)
④接口的子类
-可以是抽象类。但是意义不大。
-可以是具体类。要重写接口中的所有抽象方法。(推荐方案)

3.接口成员特点

成员变量
只能是常量,默认修饰符 public static final。
构造方法
没有,因为接口主要是扩展功能的,而没有具体存在。
成员方法
只能是抽象方法,默认修饰符 public abstract。

类与类,类与接口以及接口与接口的关系

类与类:
继承关系,只能单继承,但是可以多层继承。
类与接口:
实现关系,可以单实现,也可以多实现。还可以在继承一个类的同时实现多个接口。
接口与接口:
继承关系,可以单继承,也可以多继承。

抽象类和接口的区别

成员区别
抽象类 变量,常量;有抽象方法;抽象方法,非抽象方法
接口 常量;抽象方法
关系区别
类与类 继承,单继承
类与接口 实现,单实现,多实现
接口与接口 继承,单继承,多继承
设计理念区别
抽象类 被继承体现的是:”is a”的关系。共性功能
接口 被实现体现的是:”like a”的关系。扩展功能
示例:

/*
	教练和运动员案例
		乒乓球运动员和篮球运动员。
		乒乓球教练和篮球教练。
		为了出国交流,跟乒乓球相关的人员都需要学习英语。
		分析,这个案例中有哪些抽象类,哪些接口,哪些具体类。		
*/
//定义一个说英语的接口
interface SpeakEnglish {
	//说英语
	public abstract void speak();
}

//定义人的抽象类
abstract class Person {
	private String name;
	private int age;
	
	public Person() {}
	
	public Person(String name,int age) {
		this.name = name;
		this.age = age;
	}
	
	public String getName() {
		return name;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	public int getAge() {
		return age;
	}
	
	public void setAge(int age) {
		this.age = age;
	}
	
	//睡觉
	public void sleep() {
		System.out.println("人都是要睡觉的");
	}
	
	//吃饭
	public abstract void eat();
}

//定义运动员抽象类
abstract class Player extends Person {
	public Player() {}
	
	public Player(String name,int age) {
		super(name,age);
	}
	
	//学习
	public abstract void study();
}

//定义教练抽象类
abstract class Coach extends Person {
	public Coach() {}
	
	public Coach(String name,int age) {
		super(name,age);
	}
	
	//教
	public abstract void teach();
}

//定义乒乓球运动员具体类
class PingPangPlayer extends Player implements SpeakEnglish {
	public PingPangPlayer(){}
	
	public PingPangPlayer(String name,int age) {
		super(name,age);
	}
	
	//吃
	public void eat() {
		System.out.println("乒乓球运动员吃大白菜,喝小米粥");
	}
	
	//学习
	public void study() {
		System.out.println("乒乓球运动员学习如何发球和接球");
	}
	
	//说英语
	public void speak() {
		System.out.println("乒乓球运动员说英语");
	}
}

//定义篮球运动员具体类
class BasketballPlayer extends Player {
	public BasketballPlayer(){}
	
	public BasketballPlayer(String name,int age) {
		super(name,age);
	}
	
	//吃
	public void eat() {
		System.out.println("篮球运动员吃牛肉,喝牛奶");
	}
	
	//学习
	public void study() {
		System.out.println("篮球运动员学习如何运球和投篮");
	}
}

//定义乒乓球教练具体类
class PingPangCoach extends Coach implements SpeakEnglish {
	public PingPangCoach(){}
	
	public PingPangCoach(String name,int age) {
		super(name,age);
	}
	
	//吃
	public void eat() {
		System.out.println("乒乓球教练吃小白菜,喝大米粥");
	}
	
	//教
	public void teach() {
		System.out.println("乒乓球教练教如何发球和接球");
	}
	
	//说英语
	public void speak() {
		System.out.println("乒乓球教练说英语");
	}
}

//定义篮球教练具体类
class BasketballCoach extends Coach {
	public BasketballCoach(){}
	
	public BasketballCoach(String name,int age) {
		super(name,age);
	}
	
	//吃
	public void eat() {
		System.out.println("篮球教练吃羊肉,喝羊奶");
	}
	
	//教
	public void teach() {
		System.out.println("篮球教练教如何运球和投篮");
	}
}

class InterfaceDemo {
	public static void main(String[] args) {
		//测试运动员(乒乓球运动员和篮球运动员)
		//乒乓球运动员
		PingPangPlayer ppp = new PingPangPlayer();
		ppp.setName("王浩");
		ppp.setAge(33);
		System.out.println(ppp.getName()+"---"+ppp.getAge());
		ppp.eat();
		ppp.sleep();
		ppp.study();
		ppp.speak();
		System.out.println("----------------");
		
		//篮球运动员
		BasketballPlayer bp = new BasketballPlayer();
		bp.setName("姚明");
		bp.setAge(34);
		System.out.println(bp.getName()+"---"+bp.getAge());
		bp.eat();
		bp.sleep();
		bp.study();
		//bp.speak(); //没有该方法

	}
}

案例分析图:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值