多态:
(含类的向上和向下转换)
/*
** 多态:事物存在的多种形态;
** 1.多态的体现:
** 使用父类的引用指向自己子类的对象;
** 2.多态的前提:
** 必须是类与类之间的关系,要么继承,要么实现,
** 另外,子类需能覆盖父类的方法;
** 3.多态的优点:
** 大大提高了程序的扩展性;
** 4.多态的弊端:
** 只能访问父类中的成员;
*/
abstract class Animal{ //抽象的父类;
public 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("啃骨头");
}
}
class Pig extends Animal{
//重写继承而来的抽象类中的方法;
public void Eat(){
System.out.println("饲料");
}
}
class PolymorphicDemo{
public static void main(String[] args){
/* 该部分语句可以用下面的代替
Cat c=new Cat();
c.Eat();
*/
// 父类的引用Animal A指向子类的对象new Cat()
Polymorphic(new Cat());
Polymorphic(new Dog());
Polymorphic(new Pig());
System.out.println("类型向上转换。");
Animal c=new Cat(); //类型提升,向上转换;
c.Eat();
//对象c中不具有CatchMouse()方法,若要具有该方法,则:
System.out.println("对象的强制类型转换。");
//类型转换之前需先判断;
if(c instanceof Cat){ //instance: 判断所属类型;
Cat a=(Cat)c; //强制类型转换;只能将之转换为原子类;
a.CatchMouse();
}
}
/*
** 以下语句中Animal A的语句按照之前的方法是用Cat C
** 这样的话,每添加一个动物类都需要再添加一个函数;
** 而使用Animal A的方式却只需要写如下函数即可。
** 原理:不管是添加的何种动物类,
** 它们都继承自“动物”这一大父类,子类均对Eat()函数重写,
** 覆盖了父类中的Eat();
*/
// Animal A是多态的体现;
// 父类的引用Animal A指向子类的对象new Cat()
public static void Polymorphic(Animal A){
A.Eat();
}
}
多态实例:
abstract class Student{
int num=3;
public abstract void Study();
public void Sleep(){
System.out.println("Student:12点入睡。");
}
}
class BaseStudent extends Student{
int num=4;
public void Study(){
System.out.println("Base study.");
}
//部分同学休息时间不定,重写休息时间,覆盖父类休息方法;
public void Sleep(){
System.out.println("base student:11点入睡。");
}
}
class AdvStudent extends Student{
//重写抽象类中的抽象方法;
public void Study(){
System.out.println("Adv student study.");
}
}
//将多态的调用直接封装到一类类中:工具类;
class DoStudent{
//父类引用指向子类对象;
public void doSome(Student s){
s.Study();
s.Sleep();
}
}
class duotai{
public static void main(String[] args){
/*
** 未使用多态的调用;
*/
System.out.println("未使用多态调用。");
BaseStudent bs=new BaseStudent();
bs.Study();
bs.Sleep();
/*
** 使用多态的调用;
*/
System.out.println("使用多态调用。");
DoStudent ds= new DoStudent();
ds.doSome(new BaseStudent());
ds.doSome(new AdvStudent());
//多态中的成员变量;
Student Stu=new BaseStudent();
System.out.println(Stu.num); //该值输出为3;
BaseStudent Bstu= new BaseStudent();
System.out.println(Bstu.num); //该值输出为4;
}
}
多态中非静态成员函数的特点:
编译时期:审查引用型变量所属的类中是否有调用的方法;若有,则通过,反之则不通过;
运行时期:审查对象所属的类中是否有调用的方法,若有则通过,反之则不通过。
总结:成员函数在多态调用时,编译看左边,运行看右边;
多态中成员变量的特点:
无论编译和运行,都参看引用型变量;
对于静态成员函数,无论编译和运行,都参看左边(引用型变量)。
多态主板实例:
/*
** 主板实例:
** 功能:可向该主板中添加插件,如网卡,声卡...
*/
//定义同一的接口,添加的插件,如网卡,声卡等,
//通过该接口连接到主板;
interface PCI{
public void open();
public void close();
}
//主板中提供接口的使用方法;
class mBoard{
public void run(){
System.out.println("Main board run!");
}
//主板符合接口的标准;
//表示插件通过该接口可以连接到主板;
public void usePci(PCI P){
P.open();
P.close();
}
}
//要连接的插件符合接口的标准;
class netCard implements PCI{
public void open(){
System.out.println("net card open.");
}
public void close(){
System.out.println("net card close.");
}
}
//......后续有N多的插件都可以通过该方式添加
//而无需更改主板相关信息;
class soundCard implements PCI{
public void open(){
System.out.println("sound card open.");
}
public void close(){
System.out.println("sound card close.");
}
}
class MainBoard{
public static void main(String[] args){
mBoard mb= new mBoard();
mb.run();
//父类引用,指向子类对象;
mb.usePci(new netCard() );
mb.usePci(new soundCard() );
}
}
复写Object类中的equals方法
/*
** 复写object类中的equals方法;
** Object 类是所有类的上帝;
*/
class Demo{
int num;
Demo(int num){ //构造函数无返回;
this.num=num;
}
//复写equals方法;
/*
** 由于Object类中已经有了equals方法,在使用相同的功能比较不同的类型
** 时,可以采用复写的方式;
*/
public boolean equals(Object obj){
//只有同类型才能相比,先判断是否同类型;不同则直接返回false
if(!(obj instanceof Demo)){
return false;
}
//由于父类中无num变量,且obj为父类引用(多态),为了访问子类
//中的变量,需要使用强类型转换;
Demo d= (Demo)obj;
return this.num==d.num;
}
}
class objectDemo{
public static void main(String[] args){
Demo de_1=new Demo(3);
Demo de_2=new Demo(3);
System.out.println("Compare result is :"+de_1.equals(de_2));
}
}