Java基础提高篇(二)多态
2017-04-27 13:25
113 查看
在面向对象的程序设计语言中,多态是继数据抽象和继承之后的第三种特征。
不同类的对象对同一消息作出不同的响应就叫做多态。
多态存在的三个条件
1、有继承关系
2、子类重写父类方法
3、父类引用指向子类对象
多态方法调用允许一种类型表现出与其他相似类型之间的区别,只要它是从同一基类导出而来的,这种区别是根据方法行为的不同而表现出来的,虽然这些方法都可以通过同一个基类来调用。
看一个简单的多态例子
输出: BaskSport——-BASKETBALL
Demo1.p()接收一个Sport引用,同时也可以接收任何Sport的导出类,当将BaskSport引用传递给p()时,由于这是向上转型,是允许的,向上转型可能会缩小接口,但不会比父类的全部接口更窄。
输出:Demo1的私有fun方法
按道理,应该输出”Zi的fun方法”才对,但是这里有个陷阱就是Demo1的fun方法是私有的,无法被覆盖,而Zi类中的fun是新的方法。所以:只有非private方法才可以被覆盖。
2.域和静态方法
只有普通方法的调用可以是多态的,域和静态方法不能是多态的。
输出:
可以看到,当子类对象转型为父类引用时,任何域访问操作都将由编译器解析,因此不是多态的。其实在实际开发过程中,我们不会将域设置为public的,一般设置成private,因此不能直接访问它们,只能通过调用方法访问。
如果某个方法是静态的,它的行为就不具有多态性
输出:
**
静态方法是与类,而非与单个对象相关联的。**
重点是这句:((CBA)nba).f2();
如果单纯的nba.f2();那么无法编译,因为NBA类并没有f2()方法,所以必须进行向下转型,转换为CBA类型的,因为CBA类型有f2()。
向上转型和向下转型其实很好理解,小的—>大的,大的—>不能说是小的。毕竟中国是上海的,这句话要被笑话的。
友情链接:
谈谈多态
不同类的对象对同一消息作出不同的响应就叫做多态。
多态存在的三个条件
1、有继承关系
2、子类重写父类方法
3、父类引用指向子类对象
多态方法调用允许一种类型表现出与其他相似类型之间的区别,只要它是从同一基类导出而来的,这种区别是根据方法行为的不同而表现出来的,虽然这些方法都可以通过同一个基类来调用。
看一个简单的多态例子
enum Ball{ BASKETBALL,FOOTBALL } class Sport{ public void play(Ball ball){ System.out.println("Sport------"+ball); } } class BaskSport extends Sport{ @Override public void play(Ball ball) { System.out.println("BaskSport-------"+ball); } } public class Demo1 { public static void p(Sport s){ s.play(Ball.BASKETBALL); } public static void main(String[] args) { BaskSport baskSport=new BaskSport(); p(baskSport); } }
输出: BaskSport——-BASKETBALL
Demo1.p()接收一个Sport引用,同时也可以接收任何Sport的导出类,当将BaskSport引用传递给p()时,由于这是向上转型,是允许的,向上转型可能会缩小接口,但不会比父类的全部接口更窄。
多态的二个缺陷
1.“覆盖”私有方法public class Demo1 { private void fun(){ System.out.println("Demo1的私有fun方法"); } public static void main(String[] args) { Demo1 demo1 = new Zi(); demo1.fun(); } } class Zi extends Demo1{ public void fun(){ System.out.println("Zi的fun方法"); } }
输出:Demo1的私有fun方法
按道理,应该输出”Zi的fun方法”才对,但是这里有个陷阱就是Demo1的fun方法是私有的,无法被覆盖,而Zi类中的fun是新的方法。所以:只有非private方法才可以被覆盖。
2.域和静态方法
只有普通方法的调用可以是多态的,域和静态方法不能是多态的。
class NBA{ public String location="USA"; public void f(){ System.out.println(location); } } class CBA extends NBA{ public String location="CBA"; public void f(){ System.out.println(location); } } public class Demo1 { public static void main(String[] args) { NBA nba = new CBA(); String location = nba.location; System.out.println(location); nba.f(); } }
输出:
USA CBA
可以看到,当子类对象转型为父类引用时,任何域访问操作都将由编译器解析,因此不是多态的。其实在实际开发过程中,我们不会将域设置为public的,一般设置成private,因此不能直接访问它们,只能通过调用方法访问。
如果某个方法是静态的,它的行为就不具有多态性
class NBA{ public static void f1(){ System.out.println("NBA"); } public void f2(){ System.out.println("NBA----f2"); } } class CBA extends NBA{ public static void f1(){ System.out.println("CBA"); } public void f2(){ System.out.println("CBA----f2"); } } public class Demo1 { public static void main(String[] args) { NBA nba = new CBA(); nba.f1(); nba.f2(); } }
输出:
NBA CBA----f2
**
静态方法是与类,而非与单个对象相关联的。**
向下转型
class NBA{ public void f1(){} } class CBA extends NBA{ public void f1(){} public void f2(){} } public class Demo1 { public static void main(String[] args) { NBA nba = new NBA(); nba.f1(); ((CBA)nba).f2(); } }
重点是这句:((CBA)nba).f2();
如果单纯的nba.f2();那么无法编译,因为NBA类并没有f2()方法,所以必须进行向下转型,转换为CBA类型的,因为CBA类型有f2()。
向上转型和向下转型其实很好理解,小的—>大的,大的—>不能说是小的。毕竟中国是上海的,这句话要被笑话的。
友情链接:
谈谈多态
相关文章推荐
- java基础提高篇--java的三大特性--多态
- Java基础:减少对象的创建提高java性能
- Java,sql的基础书看了一堆,可很少有实际经验,感觉自己没怎么提高,大家给点意见~~谢谢~~
- java基础--多态与包
- Java学习之旅基础知识篇:面向对象之封装、继承及多态
- 黑马程序员_java基础3-面向对象(二)多态、异常、包
- java基础 ---继承和多态
- 提高程序效率的java基础知识小结【转载来源chinaitlab】
- Java基础之面向对象(四)--多态、Object类
- JAVA基础第八天学习日记_多态
- C02-程序设计基础提高班(C++)第13周上机任务-多态与虚函数
- Java基础:第三十九讲 多态
- Java 基础一些代码练习笔记(继承+接口+多态)
- Java 基础一些代码练习笔记(多态2)
- 提高java基础
- 字节码防止内存错误及提高代码质量-Java基础-Java-编程开发
- Java 基础一些代码练习笔记(多态1)
- 黑马程序员Java基础之多态与继承、覆盖与重载
- 黑马程序员_Java基础_面向对象(多态、Object类相关方法)
- Java基础_多态