您的位置:首页 > 编程语言 > Java开发

Java基础提高篇(二)多态

2017-04-27 13:25 113 查看
在面向对象的程序设计语言中,多态是继数据抽象和继承之后的第三种特征。

不同类的对象对同一消息作出不同的响应就叫做多态。

多态存在的三个条件

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 多态