本篇文章讲得内容其实很简单,虽然在课程视频中讲了一天,就是为了让学生更好的体会继承、接口、多态的应用。
主要包括:多态时调用的成员到底指父类还是子类中的成员(3);类型转换(1);将类中共同的方法抽取为接口或抽象类,提高了程序的可拓展性(1、2、4、5),当有新类创建时,在main函数中改动较少。
1、可扩展性、类型转换
abstract class Animal { abstract void eat(); } class Cat extends Animal { public void eat() { System.out.println("吃鱼"); } public void catchMouse() { System.out.println("抓老鼠"); } } class Dog extends Animal { public void eat() { System.out.println("啃骨头"); } public void seeHouse() { System.out.println("看家"); } } class AnimalDemo { public static void function(Animal a)//多态,提高扩展性 { a.eat(); } public static void main(String[] args) { Animal a=new Cat();//类型提升,向上转型 function(a); //调用子类特有方法 Cat c=(Cat)a;//向下转型,强制将父类引用转换为子类类型 c.catchMouse(); } }
2、多态练习
/* 基础班学生:吃饭,睡觉 高级班学生:吃饭,睡觉 将两类事物的共同功能进行抽取 */ abstract class Student { public abstract void study(); public void sleep() { System.out.println("躺着睡"); } } class BaseStudent extends Student { public void study() { System.out.println("学基础课"); } public void sleep() { System.out.println("坐着睡"); } } class AdvStudent extends Student { public void study() { System.out.println("学进阶课"); } } class DoStudent { public void doSome(Student stu) { stu.study(); stu.sleep(); } } class StudentDemo { public static void main(String[] args) { DoStudent s=new DoStudent(); s.doSome(new BaseStudent()); s.doSome(new AdvStudent()); } }
比4、5更进一步,把抽象类中方法覆盖后,又将其运行封装在一起。需要这样做吗?
3、多态中成员的特点
在多态中,非静态方法成员:编译时看引用变量所属类中的方法,如该方法不存在,则编译失败;运行时看对象所属类的方法,如有覆盖,运行子类方法。
对于变量和静态方法,均看引用变量所属类。
class Fu { int num=1; void method_1() { System.out.println("fu method1"); } void method_2() { System.out.println("fu method2"); } static void method_4() { System.out.println("fu method4"); } } class Zi extends Fu { int num=2; void method_1() { System.out.println("zi method1"); } void method_3() { System.out.println("zi method3"); } static void method_4() { System.out.println("zi method4"); } } class DuotaiDemo { public static void main(String[] args) { Fu f=new Zi(); f.method_1();//调用子类method_1方法 f.method_2();//调用父类method_2方法 //f.method_3();//编译失败 System.out.println(f.num);//打印父类中的num值1 Fu f1=new Zi(); f1.method_4();//调用父类method_4方法 Zi z1=new Zi(); z1.method_4();//调用子类method_4方法 } }
4、主板示例
//接口降低了耦合性,提高了程序扩展性 /* 需求:电脑运行实例 电脑运行基于主板。 */ interface PCI { public void open(); public void close(); } class MainBoard { public void run() { System.out.println("run"); } public void usePCI(PCI p)//接口型引用指向其子类对象,多态 { if(p!=null) { p.open(); p.close(); } } } class NetCard implements PCI { public void open() { System.out.println("netcard open"); } public void close() { System.out.println("netcard close"); } } class SoundCard implements PCI { public void open() { System.out.println("soundcard open"); } public void close() { System.out.println("soundcard close"); } } class MainBoardDemo { public static void main(String[] args) { MainBoard mb=new MainBoard(); mb.run(); mb.usePCI(null); mb.usePCI(new NetCard()); mb.usePCI(new SoundCard()); } }
5、数据库操作
/*需求:数据库操作 数据是用户信息 1、连接数据库 JDBC Hinbernate 2、操作数据库 CRUD增删改查 3、关闭数据库连接 */ //两种连接方式功能相同,抽象为接口 interface UserInfoDao { public void add(User user); public void delete(User user); } class UserInfoByJDBC implements UserInfoDao { public void add(User user) { //JDBC连接数据库 //使用sql添加语句添加数据 //关闭连接 } public void delete(User user) { //JDBC连接数据库 //使用sql添加语句删除数据 //关闭连接 } } class UserInfoByHinbernate implements UserInfoDao { public void add(User user) { //Hinbernate连接数据库 //使用sql添加语句添加数据 //关闭连接 } public void delete(User user) { //Hinbernate连接数据库 //使用sql添加语句删除数据 //关闭连接 } } class DBOperate { public static void main(String[] args) { UserInfoDao ui=new UserInfoByJDBC(); //连接方式发生变化时,main类只改new后面的对象 ui.add(user); ui.delete(user); } }
4、5中两个以上类功能相同,将其功能抽取为接口,通过接口引用可以操作实现该接口的类的具体对象的功能。
提高了程序的拓展性,在主方法中只用修改接口引用所指向的对象。
6、二次分发,学堂在线JAVA程序设计,郑莉老师
也不知道自己写的合不合适,以后再来看吧。
/*二次分发double dispatching: * 对于交通工具,声明一个抽象类Vehicle及两个子类Bus和Car; * 对于司机,声明一个抽象类Driver及两个子类FamaleDriver和MaleDriver; * 在Driver类中声明了抽象方法drives,在两个子类中对该方法进行覆盖; * drives接收一个Vehicle类的参数,当不同类型的交通工具被传送到此方法时, 可以输出具体的交通工具; * 所有类都放在drive包中。 */ public class DriverTest { public static void main(String[] args) { Driver fd=new FamaleDriver(); Driver md=new MaleDriver(); Bus b=new Bus(); Car c=new Car(); fd.drives(c); //A famale driver drives a car. md.drives(b); //A male driver drives a bus. } } abstract class Driver{ String type="driver"; public void drives(Vehicle v){ System.out.print("A "+type+" drives a "); v.print(); } } class FamaleDriver extends Driver{ public FamaleDriver(){ type="famale driver"; } } class MaleDriver extends Driver{ public MaleDriver(){ type="male driver"; } } abstract class Vehicle{ public abstract void print(); } class Bus extends Vehicle{ public void print(){ System.out.println("bus"); } } class Car extends Vehicle{ public void print(){ System.out.println("car"); } }