**Javase 重要知识点总结 day10
关键词 :抽象类 接口 多态
#一、抽象类
抽象类—— 可以限定子类必须具有的功能。
有什么用?
为所有的子类提供一个模板,规定所有的子类 共同的特征和功能。子类会进行方法的重写 ,进行修改和拓展。
(抽象类,不一定非要 有抽象方法。可有,可无。可以用super 调用相关的方法)
抽象类: 只约定了 类的抽象行为,没有具体实现相应的行为。
场合:
1) 此类太抽象不适合创建对象;
2)用的都是子类的对象;
3) 此类只是一个 模板的作用。子类 在 此 基础上 进行 扩充 和 修改。
points:
抽象类的抽象方法子类必须重写?why?
如果子类不重写抽象方法,那调用的方法,就空空的,没有任何实现,什么都做不了,没有语句体。那要它干嘛。对吧。
注意:3
抽象方法可以规定子类必须具有的大概特征、功能。具体功能,子类可以重写方法,自己根据自身情况自己添加定义。
是抽象方法必须重写,不是,不需要重写。
语法;
(有 抽象方法、普通方法、静态方法,子类只需要重写抽象方法就可以了)
普通方法例如:
default 方法名(){ }
案例:
package day0924;
abstract class TrafficTool{
private int count;
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
// public void run() {
// System.out.println(“行驶”);
// }
public abstract void run();
}
class Car extends TrafficTool{
@Override
public void run() {
System.out.println(“汽车在公路上行驶”);
}
}
class Tube extends TrafficTool{
@Override
public void run() {
System.out.println(“地铁在隧道中行驶”);
}
}
public class TestTrafficTool {
public static void main(String[] args) {
Car car = new Car();
car.run();
Tube tube = new Tube();
tube.run();
// TrafficTool tool = new TrafficTool();
}
}
抽象类使用注意:
1) 抽象类不能创建对象;
2) 抽象类中 可以定义抽象方法;——有一些是抽象方法,一些可以不是抽象方法?试一下
3) 普通子类 必须重写实现抽象父类中的所有 抽象方法(抽象子类除外)
4) 构造不能是抽象的;
5) abstract 修饰符不能与 private ,final ,static 一起使用。
(getSuperClass():Class:获得该类型的直接父类,如果该类型没有直接父类,那么返回null。
getInterfaces():Class[]:获得该类型实现的所有接口。)
#二、接口
接口:一种规则,一组功能的封装。
备注:
接口— — 可以把某个 、某些 功能(特别的,or升级的)封装成一个接口类。 ——有点像,一个协议,一个规则。谁实现了它,谁就得遵守。
public
默认 {
}
JDK 8.0 接口的成员:
1) 接口中的所有成员 public;
2) 常量 public static final;
3) 抽象方法 public abstract 的。—— 当然 你不写,他也会隐式的补全 public abstract void 方法名();。
5) default 方法名(){ }—— 这是默认方法 , default 不是默认访问权限。
—— so,实现类只需要重写抽象方法就可以了,其他的default 方法和static 方法,都不需要重写。
案例:
package day0924;
interface WebBank{
// public abstract void webService();
void webService();
}
/*实现类/
class Jingdong implements WebBank{
@Override
public void webService() {
System.out.println(“京东实现了网上支付功能”);
}
}
class Taobao implements WebBank{
@Override
public void webService() {
System.out.println("淘宝实现了网上支付");
}
}
public class TestWebBank {
public static void main(String[] args) {
Jingdong jd = new Jingdong();
jd.webService();
Taobao taobao = new Taobao();
taobao.webService();
}
}
注意:
1. 接口不能创建对象;
2. 普通的实现类 必须重写实现 接口中的所有抽象方法(抽象的实现类除外);
3.实现类 可以 实现多个接口的功能;—— 实现多个接口,就意味着,拥有了多个接口的功能。
4.接口之间可以继承 ,可以多继承。
接口的继承相当于,功能的合并。把很多接口的功能合并到一个接口上。
5.实现接口——和继承一样,意味着拥有了这个接口的方法和功能、可以直接直接调用——同时也拥有了,接口的成员变量。
案例2:
package day0924;
interface ThreeElectric{
void ThreeService();// 三项电
}
interface TwoElectric{
void twoService();// 两项电
}
interface Socket extends ThreeElectric,TwoElectric{
void socketService();
}
class Goods{}
class Computer extends Goods implements Socket {
@Override
public void twoService() {
System.out.println("外置设备 使用亮相电供电成功");
}
@Override
public void ThreeService() {
System.out.println(" 笔记本使用三项电供电成功");
}
@Override
public void socketService() {
System.out.println("插排供电");
}
}
//class Computer implements ThreeElectric,TwoElectric{
// @Override
// public void twoService() {
// System.out.println(“外置设备 使用亮相电供电成功”);
// }
// @Override
// public void ThreeService() {
// System.out.println(" 笔记本使用三项电供电成功");
// }
//}
public class TestElectric {
public static void main(String[] args) {
// IceBox ice = new IceBox();
// ice.ThreeService();
Computer computer = new Computer();
computer.socketService();
computer.ThreeService();
computer.twoService();
}
}
//class IceBox implements ThreeElectric{
// @Override
// public void ThreeService() {
// System.out.println(“冰箱使用三项电供电成功”);
// }
//}
其它成员:
package day0924;
interface Info{
// public static final int N = 11;
int N = 11;
// 默认 public
default void df() {
System.out.println(“df”);
}
// public 静态方法 ,子接口 和 实现类 都不能继承。
static void sf() {
System.out.println(“sf”);
}
}
class InfoImpl implements Info{
public void func() {
// N = 22;// final 常量不允许修改
System.out.println(N);// 继承了 ,直接用 Info.N
df();// 默认方法
Info.sf();
}
}
public class TestInfo {
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
抽象类 和 接口 的异同:
相同点:
1)都不能创建对象;
2) 都可以定义抽象方法;
3) 使用:子类 实现或实现类实现。
不同:
接口设计:
1)同一个应用程序,接口用于降低模块之间的耦合连接。
鸟
吃();
接口中:飞()
鸵鸟 麻雀 实现 飞接口
2)不同应用程序。程序之间连接的桥梁,是通信的规则。
抽象类:
为所有的子类提供了模板,提供了一部分功能,为子类提供了一部分不可分割的功能。
类。 ThrafficTool
继承
子类。 Car
get points:
1)类是用来创建对象的,接口——》是一组功能封装而已。
2)interface A implements B ——》 A 拥有了类B 的功能,也包括属性变量。
#三、UML之类图
1.泛化
体现: 继承 类 和 类
表示:继承
语法:
class 父类{}
class 子类 extends 父类{}
2.实现
体现: 类 和 接口的关系。
表现:实现 ,实现类 实现接口的功能。
语法:
interface 接口名{}
class 实现类 implements 接口{}
3.依赖
体现:类 和 类。
表现: 使用;
语法:被依赖的类(必需品) 作为 依赖类(主体类) 的 局部变量。
class 人{
void 开发程序(计算机类型 计算机){
}
}
class 计算机{ }
//------------------------------------------------------------------
class 手机类{
void 充电(){
电池类 电池 = new 电池类();// 局部变量
电池.蓄电();
}
}
class 电池类{}
依赖类——主体 (手机)、被依赖类(需要的物品、依赖品)
两种依赖 形式:
1) 在主体的方法中传参时,方法( 依赖品 )
2) 在主体的方法 语句体内,{ 新建 new 依赖品的对象 }
Another points :
1.class 手机类{
void 充电(){
电池类 电池 = new 电池类();// 电池在此 作为的是一个 局部变量
电池.蓄电();
4.关联
体现:类和 类。
表现:拥有
语法: 被拥有者 作为 拥有着 的 成员变量
class 学生类{
课程类 课程 = new 课程类();// 成员变量
}
class 课程类{}
**聚集: 强关联。 聚合。**
体现:类和类。
表现: 整体 和 局部。(局部离开了整体可以独立存在)
语法:局部类 作为整体类的 成员变量
class 计算机类{
鼠标 鼠标 = new 鼠标();
键盘 键盘 = new 键盘():
}
class 鼠标{}
class 键盘{}
**组合: 强聚集。**
体现:类 和类。
表现:整体和局部的关系(局部离开了整体不能独立存在);
语法: 局部类作为整体类的成员变量;
class 狼{
心脏 心 = new 心脏();
四肢 四肢= new 四肢();
}
class 心脏{}
class 四肢{}
#四、多态
有什么用?
1. 更容易更换子类对象;
* 2. 可以使用 父类类型 表示 所有的子类类型的对象。
可以随意 更换子类 进行传参(例如(Object object)父类可以兼容所有的子类型,进行隐式转换),或者调用子类中的方法(父类中也有的方法)。
子类和其他类 以及 父类之间的耦合度较低。
(后面会讲,集合容器可以有很多类型的容器)
可以向后兼容,很多类 ,版本,类型。
Teacher guofu = new SqlTeacher();
guofu.giveLesson();// 对象是什么类型 ,就调用哪一个类中的方法。
**多态 ——黑色打印机,打印的是黑色打印机的方法(方法进行重写了 打印机1的方法)**
特点:
1.方法重写; 2. 父类引用 -》 子类对象;接口引用-》 实现类对象
编译看左边(看父类有没有相同的方法,没有编译会报错。),执行看右边(如果父类和子类有同名同参数类型的方法,那就执行右边)。
优点作用:
1. 更容易更换子类实现;
2. 可以用一种类型 表示(兼容)多种类型
多态表现:
1) 类多态
普通类:
package day0924;
/*普通类:多态/
class Teacher{
public void giveLesson() {
System.out.println(“讲数学课”);
}
}
class JavaTeacher extends Teacher{
@Override
public void giveLesson() {
System.out.println(“讲Java课”);
}
// 子类独特的功能
public void sing() {
System.out.println(“唱歌”);
}
}
class SqlTeacher extends Teacher{
@Override
public void giveLesson() {
System.out.println(“讲Sql课”);
}
// 子类独特的功能
public void dance() {
System.out.println(“跳舞”);
}
}
public class TestTeacher {
public static void main(String[] args) {
Teacher guofu = new SqlTeacher();
// JavaTeacher guofu = new JavaTeacher();
guofu.giveLesson();// 对象是什么类型 ,就调用哪一个类中的方法。
// guofu.sing();// 子类独特的功能被屏蔽了
// Teacher guoxiang = new SqlTeacher();
// SqlTeacher guoxiang = new SqlTeacher();
// guoxiang.giveLesson();
// guoxiang.dance();// 子类独特的功能被屏蔽了
}
}
抽象类:
package day0924;
/*抽象类:多态/
abstract class TrafficTool{
private int count;
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
// public void run() {
// System.out.println(“行驶”);
// }
public abstract void run();
}
class Car extends TrafficTool{
@Override
public void run() {
System.out.println(“汽车在公路上行驶”);
}
}
class Tube extends TrafficTool{
@Override
public void run() {
System.out.println(“地铁在隧道中行驶”);
}
}
public class TestTrafficTool {
public static void main(String[] args) {
// 多态
TrafficTool car = new Car();
car.run();
// Car car = new Car();
// car.run();
TrafficTool tube = new Tube();
tube.run();
// Tube tube = new Tube();
// tube.run();
}
}
2) 接口多态
package day0924;
/*接口:多态/
interface WebBank{
// public abstract void webService();
void webService();
}
/*实现类/
class Jingdong implements WebBank{
@Override
public void webService() {
System.out.println(“京东实现了网上支付功能”);
}
}
class Taobao implements WebBank{
@Override
public void webService() {
System.out.println("淘宝实现了网上支付");
}
}
public class TestWebBank {
public static void main(String[] args) {
WebBank jd = new Jingdong();
jd.webService();
// Jingdong jd = new Jingdong();
// jd.webService();
WebBank taobao = new Taobao();
taobao.webService();
// Taobao taobao = new Taobao();
// taobao.webService();
}
}
3) 参数多态
points:
- 父类中 有的(变量和方法)—— 子类才可以调用
- 不管多少子类 ,调用的功能方法(名称)都是一样的(方法,里面的行为,可以随便定义)。
————————就是,屏蔽了 所有子类 特有的功能。——子类独有的,特有的功能,都不能用。
3.例如 Annimal an = new dog();
Annimal bb= new cat();
就是说多态左边的 式子 (Annimal 对象名 ),创建对象时——>对于 所有的子类 都可以使用。
注释:Base base = new dog( );
1.左边 : 声明作用域——Base base
在栈内存中,开辟了一个小空间 ,——暂时是空的,接下来用来存储 (dog 类型对象的)地址值,这个小空间的名称是 base (只是一个名称)
2.右边 new dog ( );
在堆内存中开辟了一个空间 ,存储着 对象的一些信息(成员变量 name、age 、方法 run、等 )
3.把 堆内存中开辟出 对象的地址值 ——》赋值给 base
运行:
例如 调用run方法时, 先查看父类有没有 相应的功能——————父类Base 有,OK,你可以执行子类中run方法 ————父类Base 没有,ok ,系统就会报出编译出错。Error.
多态不能调用子类特有的功能, (只能是共性的),如果你强用——》 就会出现class castexception,类型转换异常
如果使用多态时,你想调用子类特有的功能,怎么办?
进行类型转换,强制转换:
Pet pet= new dog( ); ——》 Pet 类型转换为——》dog 类型
1.多态应用
2.运算符
if(pet.instanceof dog ){ }—— 判断 对象pet是不是 dog 类
\3.类型转换
向上类型转换——》 就是子类——》转化成父类 ,在传参数中,经常用。
例如 Pet pet = dog; // 计算机进行了 隐式转换 Pet pet = (Pet) dog。
向下转换——》 就是父类——》转化成子类,这样 对象就可以调用子类特有的功能了。
例如 传过来的是Pet 父类对象,可以进行——》Dog dog =(Dog) pet;
package day0924;
class Pet{
private String name;
public Pet(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void eat() {
System.out.println(“吃”);
}
}
class Dog extends Pet{
public Dog(String name) {
super(name);
}
@Override
public void eat() {
System.out.println(“小狗吃骨头”);
}
public void run() {
System.out.println(“小狗跑了”);
}
}
class Cat extends Pet{
public Cat(String name) {
super(name);
}
@Override
public void eat() {
System.out.println(“小猫吃鱼”);
}
public void play() {
System.out.println(“小猫去玩儿了”);
}
}
class PetHospital{
// 看病
// Pet pet = wangwang; Pet pet = new Dog(); 向上类型转换
// Pet pet = xiaohua; Pet pet = new Cat();
public void treatment(Pet pet) {// ,Cat
System.out.println(“给:” + pet.getName() + “看病”);
pet.eat();
// pet.run();// 子类独特的功能被屏蔽了
// pet.play();
if(pet instanceof Dog) {
Dog dog = (Dog)pet;// Pet -> Dog 向下类型转换 ,需要强转
dog.run();
}else if(pet instanceof Cat) {
Cat cat = (Cat)pet;
cat.play();
}
}
}
public class TestPetHospatil {
public static void main(String[] args) {
PetHospital hos = new PetHospital();
Dog wangwang = new Dog("旺旺");
hos.treatment(wangwang);
Cat xiaohua = new Cat("小花");
hos.treatment(xiaohua);
}
}
类的三层架构
三层:
第一层 interface ——规定了它们最普通、通用的功能
第二层: 抽象类—— 规定了它们必须具有的功能,是一个模板。
第三层:普通类—— 然后普通类,会根据自身特点 重写功能,这样就会有很多不同的子类供你,选择了。