多态性、instanceof关键字、抽象类应用、接口应用
多态性
什么是多态性?
对象在运行过程中的多种形态
多态性可以分成两类:
(1)方法的重载与重写
(2)对象的多态性
例如:
用父类的引用指向子类对象(用大的类型去接受小的类型,向上转型、自动转换)
Chicken home=new HomeChicken();
结论:
在编程时针对抽象类型的编写代码,称为面向抽象编程(或面向接口编程)
父类都通常定义为抽象类或接口
对象的多态性:
对象的多态性是从继承关系中的多个类而来 向上转型:将子类实例转换为父类引用 格式:父类 父类对象=子类实例;->自动转换 以基本数据类型操作为例:int i='a'; (因为char的容量比int小,所以可以自动完成) 向下转型:将父类实例转换为子类引用 格式:子类 子类对象=(子类)父类实例;强制转换 以基本数据类型操作为例:char c=(char)97; 因为整型是4个字节比char2个字节要大,所以需要强制完成
多态性小结:
1、方法的重载与重写就是方法的多态性的表现
2、多个子类就是父类中的多种形态
3、父类引用可以指向子类对象,自动转换
4、子类对象指向父类引用需要强制类型(注意:类型不对会报异常)
5、在实际开发中尽量使用父类引用(更利于扩展)
instanceof关键字
instanceof是用于检查对象是否为指定的类型,通常在把父类引用强制转换为子类引用时要使用,以避免发生类型转换异常(ClassCastException)
语法格式如下:
对象 instanceof 类型 --返回boolean类型值 示例: if(homeChicken instanceof Chicken){ //... } 该语句通常用来判断一个对象是否为某个类的实例,是返回true,否返回false
父类的设计原则:
通过instanceof关键字,我们可以很方便的检查对象类型,但如果一个父类的子类过多,这样的判断还是显得很繁琐,那么如何去设计一个父类呢?
1、父类通常情况下都设计为抽象类或接口,其中优先考虑接口,如接口不能满足才考虑抽象类。
2、一个具体的类尽可能不去继承另一个具体的类,这样的好处是无需检查对象是否为父类的对象
【例子】
package HeadFirst; /* 多态性 */ public class Test28 { public static void main(String[] args) { Chicken1 hc = new HomeChicken("家鸡"); Chicken1 yc = new YeChicken("野鸡"); eat(hc); eat(yc); Chicken1 jjc = new JianJiaoChicken("尖叫鸡"); eat(jjc); eat(hc); } //抽象(粒度) 面向抽象编程(面向接口编程) public static void eat(Chicken1 c) {//用父类Chicken1可以传入任何子类,注意不能用某一子类 System.out.println("鸡吃饭"); c.eat();//调用对应对象中的eat()方法 //当我们需要把父类的实例强制转换为子类引用时,为了避免类型转换异常java.lang.ClassCastException //那么我们需要在转换之前作类型检查(判断) if (c instanceof JianJiaoChicken) {//(or Chicken1)成立的条件是,对象本身及对象的父类型,都可以通过检查 JianJiaoChicken jc = (JianJiaoChicken) c;//大的类型转换为小的类型,强制转换(向下转型) jc.song(); } } } //鸡 abstract class Chicken1 { private String name; public Chicken1() { } public Chicken1(String name) { this.name = name; } public void setName(String name) { this.name = name; } public String getName() { return name; } public abstract void eat(); } //家鸡 class HomeChicken extends Chicken1 { public HomeChicken(String name) { super(name); } public void eat() { System.out.println(this.getName() + ",我爱吃米"); } } //野鸡 class YeChicken extends Chicken1 { public YeChicken(String name) { super(name); } public void eat() { System.out.println(this.getName() + ",我爱吃虫子"); } } //尖叫鸡 class JianJiaoChicken extends Chicken1 { public JianJiaoChicken(String name) { super(name); } public void eat() { System.out.println(this.getName() + ",我爱吃虫子"); } public void song() { System.out.println(this.getName() + ",我会唱歌"); } } 鸡吃饭 家鸡,我爱吃米 鸡吃饭 野鸡,我爱吃虫子 鸡吃饭 尖叫鸡,我爱吃虫子 尖叫鸡,我会唱歌 鸡吃饭 家鸡,我爱吃米
抽象类应用
模板方法模式
模板方法模式(Template Method):定义一个操作中的算法的骨架,而将一些可变部分的实现延迟到子类中。模板方法模式使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤。
【例子】
package HeadFirst; /* 模板方法模式(Template Method):定义一个操作中的算法的骨架,而将一些可变部分的实现延迟到子类中。 模板方法模式使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤。 */ public class Test29 { public static void main(String[] args) { UserManager um=new UserManager(); um.action("admin","add"); } } abstract class BaseManager { public void action(String name, String method) { if ("admin".equals(name)) { execute(method); } else { System.out.println("你没有操作权限,请联系管理员"); } } public abstract void execute(String method);//将execute方法留到子类去实现 } class UserManager extends BaseManager { public void execute(String method) { //用户是否登录的验证 //验证成功后才可以执行以下操作 if ("add".equals(method)) { System.out.println("执行了添加操作"); } else if ("del".equals(method)) { System.out.println("执行了删除操作"); } } } 执行了添加操作
接口应用–策略模式
策略模式:定义了一系列的算法,将每一种算法封装起来并可以相互替换使用,策略模式让算法独立于使用它的客户应用而独立变化。
OO设计原则:
1、面向接口编程(面向抽象编程)
2、封装变化
3、多用组合,少用继承
【例子】
package HeadFirst; /* 策略模式:定义了一系列的算法,将每一种算法封装起来并可以相互替换使用,策略模式让算法独立于使用它的客户应用而独立变化。 */ public class Test30 { public static void main(String[] args) { BaseService user = new UserService();//抽象类不能用来创建对象,所以用抽象类引用指向其实现类的对象 user.setISave(new NetSave());//调用父类中的方法,传入其他类的对象 user.add("user");//调用父类中的方法,传入参数 } } //把可变的行为抽象起来,定义一系列的算法 interface ISave { public void save(String data); } class FileSave implements ISave { public void save(String data) { System.out.println("把数据保存到文件中..." + data); } } class NetSave implements ISave { public void save(String data) { System.out.println("把数据保存到网络上..." + data); } } abstract class BaseService { private ISave iSave; public void setISave(ISave iSave) { this.iSave = iSave; } public void add(String data) { System.out.println("检查数据合法性。。。"); iSave.save(data); System.out.println("数据保存完毕。"); } } class UserService extends BaseService { } 检查数据合法性。。。 把数据保存到网络上...user 数据保存完毕。
- java自学笔记之抽象类,接口,对象的多态性,instanceof关键字
- 面向对象高级——instanceof关键字的使用以及抽象类与接口的应用
- 面向对象高级续2(instanceof关键字、抽象类和接口的应用、Object类、包装类)
- JAVA笔记6__抽象类/接口/多态/instanceof关键字、父类设计法则
- 第9天 final关键字、抽象类、接口、多态
- 漫谈-----抽象类与接口的应用(一)
- Java面向对象高级--抽象类与接口的应用
- 静态、抽象类、加载类、接口,关键字 --小丑
- 抽象类和接口的应用
- “黑马程序员”Java中final关键字,抽象类与接口
- 关于final关键字和抽象类,接口
- 抽象类和接口的区别与应用
- 为什么j2EE应用,接口实际使用,多于抽象类
- Java入门—static关键字、抽象类与接口
- Java笔记2 面向对象<3>final关键字、抽象类、模板方法模式、接口
- JAVA接口 ,抽象类的应用
- [drp 6]接口和抽象类的区别,及其应用场景
- final关键字、抽象类、接口
- 【学Java的第十天+十一天】final关键字,继承,抽象类,接口
- Python基础-接口与归一化设计、抽象类、继承顺序、子类调用父类,多态与多态性