eleven接口、多态
能够写出接口的定义格式
public interface 接口名 {
public static final 数据类型 名称 = 数据值;
//抽象方法: 必须使用实现类对象调用
void method();
//默认方法: 必须使用实现类对象调用
public default void show() {...}
//静态方法: 必须使用接口名调用
public static void fun(){...}
}
能够写出接口的实现格式
public class 类名 implements 接口名 {
//覆盖重写所有的抽象方法
//静态方法不存在覆盖重写
//默认方法可以选择性的覆盖重写,必须去掉default关键字
}
能够说出接口中的成员特点
能够说出多态的前提
1.必须要有继承/接口实现
2.必须要有父类引用指向子类对象(父类/接口类型的变量 保存 子类/实现类对象的地址值)
3.必须要有方法的覆盖重写,否则失去多态的意义
能够写出多态的格式
父类类型 对象名称 = 子类对象;
接口类型 对象名称 = 实现类对象;
能够理解多态向上转型和向下转型
向上转型:
多态的本质就是向上转型 把子类对象当成父类类型使用
//Animal a = new Dog();//转型之后只能调用父类中的规定的方法
Animal a = new Cat();//转型之后只能调用父类中的规定的方法
向下转型: 把子类对象转换成子类自己的类型
转后类型 对象名 = (转后类型)转前变量;
Dog dog = (Dog)a;
判断类型: instanceof
a instanceof Dog: 判断引用变量a如果保存的是Dog类型的对象,返回true,否则返回false
接口、多态
今日内容介绍
接口 多态
第一章 接口
1.1 接口的概念【重点】
1.概念:对外暴露的规则/规范/标准,只要符合该规则/规范/标准的东西都可以使用2.接口,是Java语言中一种引用类型,编译后也有对应的class文件,是方法的汇总 3.作用: 实现对类的功能的扩展,解决java中类的单继承的局限性
1.2 接口中可以定义的内容【重点】
1.抽象方法: public abstract 返回值类型 方法名称(形式参数列表...); 2.默认方法【jdk8开始】: public default 返回值类型 方法名称(形式参数列表...) {...} 3.静态方法【jdk8开始】: public static 返回值类型 方法名称(形式参数列表...) {...} 4.常量: public staitc final 数据类型 变量名称 = 数据值;注意:接口在设计之初,目的只是为了制定一套规则/规范/标准,所以设计之初接口中只能定义抽象方法和常量必须要掌握接口的定义格式和接口中抽象方法的定义和使用格式【最重要】
1.3 接口的定义格式【重点】
类的定义格式【复习】public class 类名 {//成员变量//成员方法//构造方法//静态方法 } 接口的定义格式public interface 类名 {//常量//抽象方法//默认方法//静态方法 }
1.4 接口中抽象方法的定义格式和使用【重点】
/*1.接口中抽象方法的定义格式public abstract 返回值类型 方法名称(形式参数列表...);注意:(1)和以前定义方法格式相同,但是需要去掉{},添加abstract(2)返回值类型和参数列表根据需求确定(3)接口中抽象方法,有默认修饰符public abstract,不写也有抽象类中抽象方法必须写public abstract,不能省略 2.接口中抽象方法的使用(1)不能直接创建接口的对象(2)定义实现类 实现 接口 关键字 implements格式:public class 类名 implements 接口A,接口B {//覆盖重写接口中的所有的抽象方法}(3)实现类中覆盖重写接口中的所有的抽象方法去掉abstract关键字,添加{}快捷键: ctrl + i(4)创建实现类对象(5)使用实现类对象调用方法 */ //USB接口 public interface USB {//抽象方法//开启功能public abstract void open();//抽象方法: public abstract 是默认修饰符,可以省略//关闭功能void close(); }
//USB接口实现类U盘 public class UDisk implements USB {@Overridepublic void open() {System.out.println("U盘已经开启....");}@Overridepublic void close() {System.out.println("U盘已经关闭....");} }
//USB接口实现类扫描仪 public class HMScanner implements USB {@Overridepublic void open() {System.out.println("扫描仪已经打开...");}@Overridepublic void close() {System.out.println("扫描仪已经关闭...");} }
//测试类 public class Demo01Inter {public static void main(String[] args) {//创建实现类对象UDisk uDisk = new UDisk();//实现类对象调用成员方法uDisk.open();uDisk.close();System.out.println("=================="); //创建实现类对象HMScanner hmScanner = new HMScanner();//实现类对象调用成员方法hmScanner.open();hmScanner.close();} }
1.5 接口中默认方法的定义格式和使用【了解】
/*接口中默认方法的定义格式和使用问题:定义接口后,有很多实现类在使用接口,如果对接口功能升级添加了新的抽象方法导致所有的实现类必须修改代码,太麻烦解决方案: 默认方法默认方法的定义格式:public default 返回值类型 方法名称(形式参数列表...){//方法体;}默认方法的使用: 只能使用实现类对象调用默认方法注意:1.接口中的默认方法,不强制要求实现类进行覆盖重写2.但是实现类可以根据需求,选择性的覆盖重写接口中的默认方法3.如果实现类覆盖重写接口中的默认方法,必须去掉default关键字 */ //定义接口 //USB接口 public interface USB {//抽象方法//开启功能public abstract void open();//抽象方法: public abstract 是默认修饰符,可以省略//关闭功能void close();//默认方法public default void driver() {System.out.println("USB接口提供的默认驱动程序....");} }
//USB接口实现类U盘 public class UDisk implements USB {@Overridepublic void open() {System.out.println("U盘已经开启....");}@Overridepublic void close() {System.out.println("U盘已经关闭....");}//该实现类发现接口中的默认方法可以满足需求,就不需要重写 }
//USB接口实现类扫描仪 public class HMScanner implements USB {@Overridepublic void open() {System.out.println("扫描仪已经打开...");}@Overridepublic void close() {System.out.println("扫描仪已经关闭...");}//该实现类发现接口中的默认方法无法满足需求,进行了覆盖重写@Overridepublic void driver() {System.out.println("使用扫描仪专用驱动");} }
public class Demo01Inter {public static void main(String[] args) {//创建实现类对象UDisk uDisk = new UDisk();//实现类对象调用成员方法uDisk.open();uDisk.close();//实现类对象调用默认方法uDisk.driver();System.out.println("==================");//创建实现类对象HMScanner hmScanner = new HMScanner();//实现类对象调用成员方法hmScanner.open();hmScanner.close();//实现类对象调用默认方法hmScanner.driver(); } }
1.6 接口中的静态方法的定义和使用【了解】
/*1.定义格式public static 返回值类型 方法名称(形式参数列表...) {方法体;}2.使用格式: 只能使用接口名称调用接口中的静态方法3.注意:(1)接口中的静态方法,属于接口本身,与实现类无关,在实现类中不存在覆盖重写(2)类中的静态方法,属于类本身,与接口无关,与对象无关(3)类中的静态方法:名直接调用 ---推荐使用对象直接调用 ---不推荐使用总结: 静态的内容要么用接口名称调用,要么用类名称调用 */ //USB接口 public interface USB {//抽象方法//开启功能public abstract void open();//抽象方法: public abstract 是默认修饰符,可以省略//关闭功能void close();//默认方法public default void driver() {System.out.println("USB接口提供的默认驱动程序....");}//静态方法public static void thanks() {System.out.println("感谢使用USB接口....");} }
//USB接口实现类U盘 public class UDisk implements USB {@Overridepublic void open() {System.out.println("U盘已经开启....");}@Overridepublic void close() {System.out.println("U盘已经关闭....");} //静态方法public static void thanks() {System.out.println("感谢使用U盘....");} }
//USB接口实现类扫描仪 public class HMScanner implements USB {@Overridepublic void open() {System.out.println("扫描仪已经打开...");}@Overridepublic void close() {System.out.println("扫描仪已经关闭...");}@Overridepublic void driver() {System.out.println("使用扫描仪专用驱动");} //静态方法public static void thanks() {System.out.println("感谢使用扫描仪....");} }
public class Demo {public static void main(String[] args) {//创建实现类对象UDisk uDisk = new UDisk();//实现类对象调用成员方法uDisk.open();uDisk.close();//实现类对象调用默认方法uDisk.driver();//实现类名称调用静态方法UDisk.thanks();//接口名称调用静态方法USB.thanks();System.out.println("==================");//创建实现类对象HMScanner hmScanner = new HMScanner();//实现类对象调用成员方法hmScanner.open();hmScanner.close();//实现类对象调用默认方法hmScanner.driver();//实现类名称调用静态方法HMScanner.thanks();//接口名称调用静态方法USB.thanks();} }
1.7 接口中成员变量的使用【了解】
/*接口中成员变量的使用接口中定义的变量,都是常量(值不可以改变)默认修饰符public static final 不写也有接口中常量默认值认为是无效的必须显式赋值接口中的常量的使用: 接口名称.常量名称建议: 接口中常量的命名全部使用大写字母,单词之间用_分隔 */ /*USB接口接口中不能定义变量,只能定义常量,而且常量有默认修饰符public static final接口中的常量默认值认为是无效的,必须显式赋值常量建议全部使用大写字母,单词之间使用_分隔*/ public interface USB {//版本public static final double VERSION = 3.0;//版本public static final int MAX_SPEED_OF_TRANSFER = 500;//最大传输速度//静态方法: 展示USB接口的相关信息public static void show() {System.out.println("USB接口版本: " + VERSION + ", 最大传输速度: " + MAX_SPEED_OF_TRANSFER + "MB/s");//show方法和内部输出的常量,都在USB接口中,所以可以省略接口名System.out.println("USB接口版本: " + USB.VERSION + ", 最大传输速度: " + USB.MAX_SPEED_OF_TRANSFER + "MB/s");}//前面定义好的其它方法省略了... }
/*接口中成员变量的使用接口中定义的变量,都是常量(值不可以改变)默认修饰符public static final 不写也有接口中常量默认值认为是无效的必须显式赋值接口中的常量的使用: 接口名称.常量名称建议: 接口中常量的命名全部使用大写字母,单词之间用_分隔 */ public class Demo04InterConstant {public static void main(String[] args) {//调用接口中的静态方法USB.show();System.out.println("--------");//直接输出接口中的常量System.out.println("USB接口版本: " + USB.VERSION);System.out.println("USB接口最大传输速度: " + USB.MAX_SPEED_OF_TRANSFER);} }
1.8 接口的多实现【重点】
/*接口的多实现在继承体系中,一个类只能继承一个父类【类的单继承: 亲爹只能有一个】。对于接口而言,一个类是可以实现多个接口的,这叫做接口的多实现【类实现接口的多实现: 干爹可以有多个】。并且,一个类能继承一个父类,同时实现多个接口。一个类能继承一个父类,同时实现多个接口格式:public class 子类名 extends 父类名 implements 接口名A,接口名B {覆盖重写抽象父类和接口中的所有的抽象方法}实现步骤:1.创建抽象父类AbstractClass,内部定义抽象方法2.创建接口MyInterA和MyInterB,内部定义抽象方法3.创建子类MyClass 继承 抽象父类AbstractClass 实现接口 MyInterA和MyInterB4.子类MyClass 覆盖重写抽象父类和接口中的所有的抽象方法5.创建子类MyClass的对象6.使用子类MyClass的对象调用方法注意:子类必须重写父类和接口中的所有抽象方法,只要有一个抽象方法没有被重写,该子类必须定义为抽象类,看MyClass02类 */
//创建抽象父类AbstractClass,内部定义抽象方法 public abstract class AbstractClass {//抽象方法public abstract void method(); }
//2.创建接口MyInterA内部定义抽象方法 public interface MyInterA {//抽象方法void show(); }
//2.创建接口MyInterB内部定义抽象方法 public interface MyInterB {//抽象方法void fun(); }
//3.创建子类MyClass 继承 抽象父类AbstractClass 实现接口 MyInterA和MyInterB public class MyClass extends AbstractClass implements MyInterA, MyInterB {//4.子类MyClass 覆盖重写抽象父类和接口中的所有的抽象方法@Overridepublic void method() {System.out.println("MyClass...method...");}@Overridepublic void show() {System.out.println("MyClass...show...");}@Overridepublic void fun() {System.out.println("MyClass...fun...");} }
/*接口的多实现在继承体系中,一个类只能继承一个父类【类的单继承: 亲爹只能有一个】。对于接口而言,一个类是可以实现多个接口的,这叫做接口的多实现【类实现接口的多实现: 干爹可以有多个】。并且,一个类能继承一个父类,同时实现多个接口。一个类能继承一个父类,同时实现多个接口格式:public class 子类名 extends 父类名 implements 接口名A,接口名B {覆盖重写抽象父类和接口中的所有的抽象方法}实现步骤:1.创建抽象父类AbstractClass,内部定义抽象方法2.创建接口MyInterA和MyInterB,内部定义抽象方法3.创建子类MyClass 继承 抽象父类AbstractClass 实现接口 MyInterA和MyInterB4.子类MyClass 覆盖重写抽象父类和接口中的所有的抽象方法5.创建子类MyClass的对象6.使用子类MyClass的对象调用方法注意:子类必须重写父类和接口中的所有抽象方法,只要有一个抽象方法没有被重写,该子类必须定义为抽象类,看MyClass02类 */ public class Demo02InterNotice {public static void main(String[] args) {//5.创建子类MyClass的对象MyClass myClass = new MyClass();//6.使用子类MyClass的对象调用方法myClass.method();myClass.show();myClass.fun();} }
/*子类继承父类 实现多个接口时,必须覆盖重写所有抽象方法,只要有一个抽象方法没有被重写,该子类必须定义为抽象类*/ public abstract class MyClass02 extends AbstractClass implements MyInterA,MyInterB {@Overridepublic void method() {System.out.println("MyClass02...method...");}@Overridepublic void show() {System.out.println("MyClass02...show...");}/*@Overridepublic void fun() {System.out.println("MyClass02...fun...");}*/ }
1.9 接口的多继承关系【了解】
接口的多继承关系子接口会拥有父接口中的所有抽象方法
public interface MyInter03A {//抽象方法void a(); }
public interface MyInter03B {//抽象方法void b(); }
public interface MyInter03C {//抽象方法void c(); }
/*接口可以多继承,子接口自动拥有父接口中的所有抽象方法*/ public interface MyInter03D extends MyInter03A, MyInter03B, MyInter03C {//抽象方法/*抽象方法a,b,c分别已经在其它接口中定义好了,此处没有必要重新定义了,只需要继承其它接口*///void a();//void b();//void c();void d(); }
public class MyInter03DImpl implements MyInter03D {@Overridepublic void a() {System.out.println("MyInter03DImpl...a...");}@Overridepublic void b() {System.out.println("MyInter03DImpl...b...");}@Overridepublic void c() {System.out.println("MyInter03DImpl...c...");}@Overridepublic void d() {System.out.println("MyInter03DImpl...d...");} }
/*接口的多继承关系子接口会拥有父接口中的所有抽象方法*/ public class Demo03Inter {public static void main(String[] args) {//创建接口实现类对象MyInter03DImpl myInter03D = new MyInter03DImpl();//调用成员方法myInter03D.a();myInter03D.b();myInter03D.c();myInter03D.d();} }
第二章 多态
2.1 生活中的多态【重点】
/*面向对象的三大特征: 封装,继承,多态封装: 提高代码的安全性继承: 提高代码的复用性多态: 提高代码的扩展性多态的概念:同一行为,通过不同的事物,可以体现出来的不同的形态。多态,描述的就是这样的状态。简单的理解: 同一个事物,表现出来不同的形态举个栗子:比如说你自己在学校中: 是一个学生在餐馆中: 是一个顾客在公司中: 是一个员工在你家里: 是妻子/丈夫回老家: 是一个孩子比如说H2O:在常温下: 是液体在高温下: 是水蒸气在低温下: 是固体冰 */
2.2 多态中的代码体现【重点】
/*多态中的代码体现1.概念:同一行为,通过不同的事物,可以体现出来的不同的形态。多态,描述的就是这样的状态。java中的多态: 指的是对象具备多态性2.举例:假设学生Student类是人Person类的子类学生 是 一个学生 //不是多态 左侧是Student类型,右侧是Student对象,左右一致Student stu = new Student();学生 是 一个人//是多态 左侧是Person类型,右侧是Student对象,左右不一致,左边是父类,右边是子类对象Person p = new Student();3.多态的前提:(1)必须要有继承或者接口实现(2)必须要有父类引用指向子类对象(父类类型的变量保存子类对象的地址值)(3)必须要有方法的覆盖重写,否则将失去多态的意义4.多态的本质(1)就是把子类对象当成父类类型使用父类引用指向子类对象(父类类型的变量保存子类对象的地址值)(2)多态的方式调用方法,方法跟着对象走 */ //定义父类 public class Person {//吃饭public void eat() {System.out.println("人吃饭...");} }//定义子类 public class Student extends Person {@Overridepublic void eat() {System.out.println("学生时间比较紧张,吃点快餐,抓紧回去学习....");} }//定义子类 public class Teacher extends Person {@Overridepublic void eat() {System.out.println("老师上课很辛苦,吃点好的,补一补...");} } //测试类 public class Demo01DuoTai {public static void main(String[] args) {//不是多态:左侧是Student类型,右侧是Student对象,左右一致Student stu = new Student();stu.eat();System.out.println("----------");//多态的方式创建Student类的对象//Person类型变量保存子类Student类型的对象Person p = new Student();p.eat();//Person类型变量保存子类Teacher类型的对象p = new Teacher();p.eat();} }
2.3 多态中成员方法的访问特点【重点】
//编译时期看左边(父类/接口),运行时期看右边(子类/实现类) //定义抽象父类Animal02 public abstract class Animal02 {//抽象方法public abstract void eat();//吃public abstract void sleep();//睡 } //定义子类Dog02 继承 抽象父类Animal02 public class Dog02 extends Animal02 {@Overridepublic void eat() {System.out.println("狗吃骨头...");}@Overridepublic void sleep() {System.out.println("小狗在眯着眼睡...");}//特有功能public void kanHome() {System.out.println("小狗在看家....");} } //测试类 public class Demo02DuoTai {public static void main(String[] args) {//多态的方式创建Animal02的对象Animal02 a = new Dog02();//调用成员方法/*在多态中把Dog02对象(子类对象)当成Animal02类型(父类)使用,此时Dog02对象表现的是父类Animal02的形态多态的方式调用eat方法编译时期: 检测父类Animal02中是否有eat方法的定义发现父类中: 有eat方法的定义,编译通过运行时期: 运行的是Dog02类中重写后的eat方法*/a.eat();/*在多态中把Dog02对象(子类对象)当成Animal02类型(父类)使用,此时Dog02对象表现的是父类Animal02的形态多态的方式调用sleep方法编译时期: 检测父类Animal02中是否有sleep方法的定义发现父类中: 有sleep方法的定义,编译通过运行时期: 运行的是Dog02类中重写后的sleep方法*/a.sleep();/*在多态中把Dog02对象(子类对象)当成Animal02类型(父类)使用,此时Dog02对象表现的是父类Animal02的形态多态的方式调用kanHome方法编译时期: 检测父类Animal02中是否有kanHome方法的定义发现父类中: 没有kanHome方法的定义,编译报错*///a.kanHome();} }
2.4 多态的好处和弊端
/*多态的好处和弊端不使用多态:好处: 可以调用子类的特有行为弊端: 扩展性极差使用多态:好处: 扩展性强弊端: 不可以调用子类的特有行为 */ //测试代码 public class Demo03DuoTai {public static void main(String[] args) {//不使用多态Dog dog = new Dog();//调用成员方法dog.eat();dog.kanHome();dog.sleep();//错误: 左右两边类型不匹配//dog = new Cat();System.out.println("----------");//使用多态Animal a = new Dog();a.eat();a.sleep();/*在多态中是把Dog对象当成父类Animal类型使用,此时Dog对象表现的是父类Animal的形态多态(父类变量)调用kanHome方法编译时期: 检测父类Animal中是否有kanHome方法的定义发现父类中: 没有kanHome方法的定义,编译失败(报错了)*///a.kanHome();//重新把Cat对象保存到父类Animal变量a中a = new Cat();a.eat();a.sleep();/*在多态中是把Cat对象当成父类Animal类型使用,此时Cat对象表现的是父类Animal的形态多态(父类变量)调用catchMouse方法编译时期: 检测父类Animal中是否有catchMouse方法的定义发现父类中: 没有catchMouse方法的定义,编译失败(报错了)*///a.catchMouse();} }
/*多态的好处:可以使用父类/接口,作为方法的参数,提高方法的扩展性问题:下面分别是用Animal的子类Dog和Cat作为方法参数,定义了两个方法Animal的子类可以有任意多个,这样定义的方法也就会有任意多个每创建一个子类,就得再添加一个方法,太麻烦解决方案:所有的子类对象,都可以当做父类类型使用所以可以使用父类类型作为方法的参数类作为方法的参数:调用方法时,传递的是该类的对象或者是该类的子类对象类的数据体现形式是对象抽象类的数据体现形式是子类对象接口的数据体现形式是实现类对象暴露新的问题: 方法内部不能直接调用子类的特有行为了(后面解决) */ //测试类 public class Demo04DuoTai {public static void main(String[] args) {//创建Dog类型的对象Dog dog = new Dog();//调用showDog传递Dog类型的对象dogshowDog(dog);System.out.println("----------------");//创建Cat类型的对象Cat cat = new Cat();//调用showCat传递Cat类型的对象catshowCat(cat);}//定义方法,参数是Dog类型public static void showDog(Dog dog) {dog.eat();dog.kanHome();dog.sleep();}//定义方法,参数是Cat类型public static void showCat(Cat cat) {cat.eat();cat.catchMouse();cat.sleep();} } //测试类 public class Demo05DuoTai {public static void main(String[] args) {//创建Dog类型的对象Dog dog = new Dog();//调用showAnimal传递Dog类型的对象dogshowAnimal(dog);System.out.println("----------------");//创建Cat类型的对象Cat cat = new Cat();//调用showAnimal传递Cat类型的对象catshowAnimal(cat);}//定义方法,参数是Animal类型public static void showAnimal(Animal a) {a.eat();a.sleep();//错误: 你传递的所有对象都被当成Animal类型使用//然而Animal类型中没有定义kanHome和catchMouse方法//a.kanHome();//a.catchMouse();}}
2.6 多态中的向上向下转型
/*多态中的向上转型多态的本质(父类引用指向子类对象): 就是向上转型类似于 基本类型的自动类型转换取值范围小的数据或者变量可以直接赋值给取值范围大的变量int a = 100;//int: 占4个字节double d = a;//double: 占8个字节不需要进行特殊的处理多态中的向下转型类似于 基本类型的强制类型转换取值范围大的数据或者变量不可以直接赋值给取值范围小的变量double d2 = 100;//double: 占8个字节int c = (int)d2;//int: 占4个字节强制类型转换:转后类型 对象名称 = (转后类型)转前的对象或者变量名称; 注意:多态的向下转型(强制类型转换)存在安全隐患如果转换前的类型和转换后的类型不一致,就会报出类型转换异常(ClassCastException)如何解决这个问题呢? */ public class Demo06DuoTai {public static void main(String[] args) {//多态的方式创建Animal类型的对象: 向上转型Animal a = new Dog();//此时只能直接调用Animal中规定好的方法a.eat();a.sleep();/*在多态中是把Dog对象当成父类Animal类型使用,此时Dog对象表现的是父类Animal的形态多态(父类变量)调用kanHome方法编译时期: 检测父类Animal中是否有kanHome方法的定义发现父类中: 没有kanHome方法的定义,编译失败(报错了)*///a.kanHome();//把Cat对象重新存储到Animal变量中a = new Cat();//向下转型: 把Animal类型的变量a,强制转换成Dog类型Dog dog = (Dog)a;//就可以调用Dog类的特有行为了dog.kanHome();} }
2.7 instanceof关键字
/*强制类型转换(向下转型)存在安全隐患:如果转后类型和创建对象的具体类型不一致,报出类型转换异常 ClassCastException如何解决呢?如果变量a指向的是Dog类型,把Animal类型的变量a强制转换成Dog类型如果变量a指向的是Cat类型,把Animal类型的变量b强制转换成Cat类型如何判断变量a指向的到底是哪种类型的对象呢?使用instanceof关键字使用格式:boolean result = 对象名 instanceof 类名如果对象名称中保存的是该类的对象,返回true。如果对象名称中保存的不是该类的对象,返回false。 */
//测试类 public class Demo07DuoTai {public static void main(String[] args) {//多态的方式创建Animal类型的对象: 向上转型//Animal a = new Dog();Animal a = new Cat();//此时只能直接调用Animal中规定好的方法a.eat();a.sleep();//如果引用变量a存储的是Dog类型的变量if (a instanceof Dog) {//向下转型: 把Animal类型的变量a,强制转换成Dog类型Dog dog = (Dog)a;//就可以调用Dog类的特有行为了dog.kanHome();}//如果引用变量a存储的是Cat类型的变量if (a instanceof Cat) {//向下转型: 把Animal类型的变量a,强制转换成Cat类型Cat cat = (Cat)a;//就可以调用Cat类的特有行为了cat.catchMouse();}} } /*测试类类作为方法的参数:调用方法时,传递的是该类的对象或者是该类的子类对象类的数据体现形式是对象抽象类的数据体现形式是子类对象接口的数据体现形式是实现类对象暴露新的问题: 方法内部不能直接调用子类的特有行为了解决方案: 使用instanceof + 向下转型 */ public class Demo08DuoTai {public static void main(String[] args) {//创建Dog类型的对象Dog dog = new Dog();//调用showAnimal传递Dog类型的对象dogshowAnimal(dog);System.out.println("----------------");//创建Cat类型的对象Cat cat = new Cat();//调用showAnimal传递Cat类型的对象catshowAnimal(cat);}//定义方法,参数是Animal类型public static void showAnimal(Animal a) {a.eat();a.sleep();//如果引用变量a存储的是Dog类型的变量if (a instanceof Dog) {//向下转型: 把Animal类型的变量a,强制转换成Dog类型Dog dog = (Dog)a;//就可以调用Dog类的特有行为了dog.kanHome();}//如果引用变量a存储的是Cat类型的变量if (a instanceof Cat) {//向下转型: 把Animal类型的变量a,强制转换成Cat类型Cat cat = (Cat)a;//就可以调用Cat类的特有行为了cat.catchMouse();}} }
第三章 综合案例1--笔记本案例【重点】
3.1 笔记本综合案例分析
定义笔记本类,具备开机,关机和使用USB设备的功能。具体是什么USB设备,笔记本并不关心,只要符合USB规格的设备都可以。 鼠标和键盘要想能在电脑上使用,那么鼠标和键盘也必须遵守USB规范,不然鼠标和键盘的生产出来无法使用; 进行描述笔记本类,实现笔记本使用USB鼠标、USB键盘USB接口,包含开启功能、关闭功能 笔记本类,包含运行功能、关机功能、使用USB设备功能 鼠标类,要符合USB接口 键盘类,要符合USB接口
3.2 笔记本综合案例实现步骤分析
1.定义USB接口抽象方法: 开启功能,关闭功能 2.定义笔记本Computer类成员方法: 开机功能,使用USB接口的功能,关机功能 3.定义鼠标Mouse类 实现 USB接口(1)覆盖重写抽象方法:开启功能,关闭功能(2)定义特有方法: 点击鼠标功能 4.定义键盘KeyBoard类 实现 USB接口(1)覆盖重写抽象方法:开启功能,关闭功能(2)定义特有方法: 敲击功能 5.测试类(1)创建笔记本Computer类的对象(2)创建外部设备鼠标Mouse类的对象(3)创建外部设备键盘KeyBoard类的对象(4)笔记本Computer类的对象调用开机功能(5)笔记本Computer类的对象调用使用USB接口的功能,传递外部设备鼠标Mouse类的对象(6)笔记本Computer类的对象调用使用USB接口的功能,传递外部设备键盘KeyBoard类的对象(7)笔记本Computer类的对象调用关机功能
3.3 笔记本综合案例代码实现
/*1.定义USB接口抽象方法: 开启功能,关闭功能*/ public interface USB {//抽象方法: 开启功能public abstract void open();//抽象方法: 关闭功能public abstract void close(); } /*2.定义笔记本Computer类成员方法: 开机功能,使用USB接口的功能,关机功能*/ public class Computer {//成员方法: 开机功能public void powerOn() {System.out.println("开机....");}/*//下面的定义方式不好,因为有多少外部设备就得定义多少方法//但是所有的外部设备都可以当成USB接口使用//可以定义方法使用USB接口作为参数//成员方法: 使用鼠标Mouse的功能public void useMouse(Mouse mouse) {}//成员方法: 使用键盘KeyBoard的功能public void useMouse(KeyBoard keyBoard) {}*///成员方法: 使用USB接口的功能/*方法被调用时:USB usb = 0x666 = new Mouse();//多态*/public void useUSB(USB usb) {//传递进来的所有外部设备都当成USB接口使用//只能直接调用USB接口中规定的方法//调用开启设备的功能usb.open();//想调用特有方法,必须进行强制类型转换//判断如果usb变量中保存的是Mouse类的对象if (usb instanceof Mouse) {//把USB类型的变量usb,强制转换成Mouse类型的变量Mouse mouse = (Mouse)usb;//调用点击鼠标的功能mouse.click();}//判断如果usb变量中保存的是KeyBoard类的对象if (usb instanceof KeyBoard) {//把USB类型的变量usb,强制转换成KeyBoard类型的变量KeyBoard keyBoard = (KeyBoard)usb;//调用敲击键盘的功能keyBoard.type();}//调用关闭设备的功能usb.close();}//成员方法: 关机功能public void powerOff() {System.out.println("关机...");} } /*3.定义鼠标Mouse类 实现 USB接口(1)覆盖重写抽象方法:开启功能,关闭功能(2)定义特有方法: 点击鼠标功能*/ public class Mouse implements USB {//(1)覆盖重写抽象方法:开启功能@Overridepublic void open() {System.out.println("鼠标开启,红灯闪闪...");}//(1)覆盖重写抽象方法:关闭功能@Overridepublic void close() {System.out.println("鼠标关闭,红灯闪闪...");}//(2)定义特有方法: 点击鼠标功能public void click() {System.out.println("点击鼠标,打开文件...");} } /*4.定义键盘KeyBoard类 实现 USB接口(1)覆盖重写抽象方法:开启功能,关闭功能(2)定义特有方法: 敲击功能*/ public class KeyBoard implements USB{//(1)覆盖重写抽象方法:开启功能@Overridepublic void open() {System.out.println("键盘开启,绿灯闪闪...");}//(1)覆盖重写抽象方法:关闭功能@Overridepublic void close() {System.out.println("键盘关闭,绿灯闪闪...");}//(2)定义特有方法: 敲击功能public void type() {System.out.println("敲击键盘,向文件中写内容...");} } //测试类 public class Demo03Computer {public static void main(String[] args) {//(1)创建笔记本Computer类的对象Computer computer = new Computer();//(2)创建外部设备鼠标Mouse类的对象Mouse mouse = new Mouse();//假设地址值: 0x666//(3)创建外部设备键盘KeyBoard类的对象KeyBoard keyBoard = new KeyBoard();//(4)笔记本Computer类的对象调用开机功能computer.powerOn();//(5)笔记本Computer类的对象调用使用USB接口的功能,传递外部设备鼠标Mouse类的对象//调用方法: computer.useUSB(0x666)computer.useUSB(mouse);//(6)笔记本Computer类的对象调用使用USB接口的功能,传递外部设备键盘KeyBoard类的对象computer.useUSB(keyBoard);//(7)笔记本Computer类的对象调用关机功能computer.powerOff();} }