A
PoiwMrJava!
11>
E:
鼻1
在程序开发中有两大错误是比较常见的:
•NullPointerException:
表示空指向异常,如果没有开辟堆内存空间,则出现此异常
•ClassCastException:
表示类转换异常,两个不相关的类的对象进行向下转型操作。
上面一个解释比较难理解哈,我们光看A类的话,我们不能知道A类有什么子类哈,但是如
果我们光看B类的话,我们可以看出B类是继承A类的话,所以得出了下面一个结论。
结论:
在进行向下转型之前,两个对象必然先发生向上转型关系,这样好建立起关系,否则两个
没有关系的对象是不能相互转型的。
对象多态性到底有那些用处呢?
如果不知道多态性的时候应该使用以下的方式编写代码,利用方法的重载完成。
classA
}
publicvoidfun2()
{
〃fun2方法调用的是funl方法
this.fun1();
}
}
classBextendsA
{
//覆写A类中的fun1()方法
publicvoidfun1()
{
System.out.println("B类===>publicvoidfun1()");
}
publicvoidfun3()
{
System.out.println("B类===>publicvoidfun3()");
}
}
classCextendsA
{
//覆写A类中的fun1()方法
publicvoidfun1()
{
System.out.println("C类===>publicvoidfun1()");
}
publicvoidfun4()
{
System.out.println("C类===>publicvoidfun4()");
}
}
publicclassDemo05
{
publicstaticvoidmain(Stringargs[])
{
fun(newB());
fun(newC());
}
//现在要求定义几个方法,可以接收父类A的子类对象
//如果不知道多态性的时候应该使用以下的方式编写代码
publicstaticvoidfun(Bb)
{
b.fun2();
}
E!
\jaua\oo4>jauAC.Jaua
B^^==>fjublicvoidfunlOC^===>publicuoidfuni<>
EJXjaua\oo4>
如果按此做法,就会面临一个很严重的问题:
•如果现在A类有30个子类,则方法要重写30遍。
所以此时就可以利用对象的多态性完成,因为所有的子类对象都可以向父类对象转换。
现在我们就只留一个fun()方法,newB(),newC()都是A类的子类哈,所以现在不管调用
时传什么子类,都调用所传子类被覆写的fun1()方法哈~~~这就是对象多态性带来的好处,
谁被其实例化就具备这样的功能哈~如果父类设计的非常的完善,则方法中会非常的好写。
已弓》百DemoBG
Xjava\oo4>j*UHaDeno06===>puhlicvoidfunl<>===>pui)licvoidfunl<)
7丑
要求:
如果传入的是B类的对象,则要求再调用fun3()方法,如果传入的是C类的对象,则要求
再调用fun4()方法。
问题:
如何去判断一个对象是否是某个类的实例呢?
这就需要instanceof关键字支持哈。
instanceof关键字
◎instanceof^j
鸯对探irstdncyof
念f]*ainsiancmofE
令:
:
处订狛圧?
:
BI坍d訂也ui反上『⑷佃詔
classA
{
publicvoidfun1()
{
System.out.println("A类===>publicvoidfun1()");
}
publicvoidfun2()
{
〃fun2方法调用的是fun1方法
this.fun1();
}
}
classBextendsA
{
}
publicvoidfun3()
{
System.out.println("B类===>publicvoidfun3()");
{
//覆写A类中的fun1()方法
publicvoidfun1()
{
System.out.println("C类===>publicvoidfun1()");
}
publicvoidfun4()
我们来判断下对象b是否是A类的实例哈,我们分析下哈,子类B可以直接向父类A转型哈,
说明父类A可以接收子类B的实例,那两者必然有关系哈,我们验证一下,结果返回true
哈,证明对象b是A类的实例哈~
E=Beno07・力霾#目
E:
DenoB?
true
E:
'^
System.out.println("B类===>publicvoidfun3()");
}
}
classCextendsA
{
//覆写A类中的fun1()方法
publicvoidfun1()
{
System.out.println("C类===>publicvoidfun1()");
}
publicvoidfun4()
{
System.out.println("C类===>publicvoidfun4()");
}
}
publicclassDemo07
{
publicstaticvoidmain(Stringargs[])
{
Bb=newB();
System.out.println(binstanceofA);
System.out.println(binstanceofB);
}
}
对象b也肯定是B类的实例哈~
E:
>jauacDenoB7.Java
E:
\java\oo^BemoO?
true
true
classA
{
publicvoidfun1()
{
System.out.println("A类===>publicvoidfun1()");
}
publicvoidfun2()
{
〃fun2方法调用的是fun1方法
this.fun1();
}
}
那相反对象a是B类的实例吗?
验证显示不是哈~说明不能向子类转换哈~
E:
\jauJauacDemoB7.Ja.ua
E;Xjaua\oo4>J*u^BemoB?
true
False
E:
\jauaXDo4>
classA
{
publicvoidfun1()
{
System.out.println("A类===>publicvoidfun1()");
}
publicvoidfun2()
{
〃fun2方法调用的是fun1方法
this.fun1();
}
}
classBextendsA
{
//覆写A类中的fun1()方法
publicvoidfun1()
{
System.out.println("B类===>publicvoidfun1()");
}
publicvoidfun3()
{
System.out.println("B类===>publicvoidfun3()");
}
}
classCextendsA
{
//覆写A类中的fun1()方法
publicvoidfun1()
{
System.out.println("C类===>publicvoidfun1()");
}
publicvoidfun4()
{
System.out.println("C类===>publicvoidfun4()");
}
}
publicclassDemo08
{
publicstaticvoidmain(Stringargs[])
{
fun(newB());
System.out.println("#########################");
fun(newC());
}
publicstaticvoidfun(Aa)
{
a.fun2();
这就是instanceof关键字的作用哈~
Ez\jaua>^io4>Jav^cDeno68,jaua
E:
\jaua\o©4>jauaBenoSSB^-=->pul)licB^;===>piit)licuciidfun3<>
C^===>pul)licuoipijihlicuoiF二Xjaium\ot)4〉
Instanceof的使用时机:
一般情况下都是在转型之前进行一下判断,这样就可以进行比较安全的转型操作。
Object类
♦祈仃的爲郁必额缔匝门gect矣够U';equalS()
®t:
1jioString()//l'.
Object
3
Iff训的爻那飙雨:
lOt^ect矣
在Java中用户所编写的一切类都是一个类的子类,称为Object类。
实际上此类默认继承了Object类,以上代码等价于以下代码:
卜classStudentextendsObject
Object类的作用:
•如果一个好的类需要覆写Object类中的三个方法:
|-publicStringtoString():
对象输出时的操作
|-publicbooleanequals(Objectobj):
对象比较时的操作
|-publicinthashCode():
返回该对象的哈希码值。
现在我们看下效果哈~
E:
\j-ava\o.java
E:
\]鼻屮日\00攻》D&F1Q09Student(?
?
5?
aef
E:
xJmueSo4
现在Student类是Object类的子类哈,那我们加上toString()看下效果
classStudent//extendsObject
{
privateStringname;
privateintage;
publicStudent(Stringname,intage)
{
this.name=name;
this.age=age;
}
}
publicclassDemo09
{
publicstaticvoidmain(Stringargs[])
{
System.out.println(newStudent("王乾",27).toString());
}
}
我们发现和没加toString()之前的效果一样哈~
E:
\jaua\oo4>javac
E:
DenoS'?
Scudent0757aef
E=
加和不加都是一样滴,那我们下面就覆写Object类的toString()方法哈~
classStudent//extendsObject
{
privateStringname;
privateintage;
publicStudent(Stringname,intage)
{
this.name=name;
this.age=age;
}
publicStringtoString()
{
return"Michael";
}