【15-1】面向对象-多态-好处&弊端&前提
//描述狗
class Dog extends Animal
{
public void eat()
{
System.out.println("吃饭");
}
public void lookHome()
{
System.out.println("看家");
}
}
//描述猫
class Cat extends Animal
{
public void eat()
{
System.out.println("鱼");
}
public void catchMice()
{
System.out.println("抓老鼠");
}
}
//进行抽取,将共性的功能抽取到父类Animal中。
abstract class Animal
{
public abstract void eat();
}
class DogAndCatTest
{
public static void main(String[] agrs)
{
//Dog d = new Dog();
//method(d);
Animal a = new Dog();
method(a);
//Cat c = new Cat();
method(new Cat());
}
/*
发现,每一个动物,都需要为这个动物单独定义一个功能。
让这个动物的对象去做事。
这个程序扩展性很差。
如何提高这个扩展性呢?
发现,既然是让动物去吃,无论是Dog还是Cat,
eat是它们的共性,于是就可以将eat进行抽取,抽取到父类中。
Dog是Animal中的一种。
Dog d = new Dog();
Ainmal a = new Dog();
Cat c = new Cat();
Animal aa = new Cat();
*/
//只要去建立Animal的引用,就可以接收所有的dog对象进来,让它们去eat
//提高了程序的扩展性。
public static void method(Animal a)
{
a.eat();
}
/*
//接收Dog,让dog去做事
public static void method(Dog d)
{
d.eat();
}
//接收Cat让Cat去做事
public static void method(Cat c)
{
c.eat();
}
*/
}
========================================================================================================
//15-2的完整例子如下:
//抽象类 动物
abstract class Animal
{
public abstract void eat();
}
//描述Dog
class Dog extends Animal
{
public void eat()
{
System.out.println("吃饭");
}
public void lookHome()
{
System.out.println("看家");
}
}
//描述猫
class Cat extends Animal
{
public void eat()
{
System.out.println("鱼");
}
public void catchMice()
{
System.out.println("抓老鼠");
}
}
class DuoTaiTest
{
public static void main(String[] args)
{
//Dog d = new Dog();
//method(d);
//Cat c = new Cat();
//method(c);
Animal a = new Dog();
//method(a);
a.eat();
//Animal a1 = new Dog();
//method(a1);
if(a instanceof Dog)
{
Dog d = (Dog)a;
d.lookHome();
}
}
//public static void method(Animal a)
//{
// a.eat();
//}
}
===========================================================================================================
【15-2】面向对象-多态-转型
//描述狗
class Dog extends Animal
{
public void eat()
{
System.out.println("吃饭");
}
public void lookHome()
{
System.out.println("看家");
}
}
//描述猫
class Cat extends Animal
{
public void eat()
{
System.out.println("鱼");
}
public void catchMice()
{
System.out.println("抓老鼠");
}
}
//进行抽取,将共性的功能抽取到父类Animal中。
abstract class Animal
{
public abstract void eat();
}
/*
多态:体现
父类的引用或者接口指向了自己的子类对象。
Dog d = new Dog(); //Dog对象的类型是Dog类型。
Animal a = new Dog(); //Dog对象的类型右边是Dog类型,左边是Animal类型。
好处:
提高了程序的扩展性。
弊端:
通过父类引用操作子类对象时,只能使用父类中已有的方法,不能操作子类特有的方法。
前提:
1,必须有关系,继承或实现。
2,通常都有重写操作
子类的特有方法如何调用呢?
Animal a = new Dog(); //Animal是父类型,new Dog()是子类对象。
但是父类型引用指向子类对象时,这就是让子类对象进行了类型的提升(向上转型),
如果想要使用子类的特有方法,只有子类型可以用。
可以向下转型,强制转换。
Animal a = new Dog();
a.eat();
Dog d = (Dog)a;//将a转型为Dog类型。向下转型
d.lookHome(); //此时就可以用这个子类的特有功能了。
向下转型什么时候用?当需要使用子类型的特有内容时。
注意:无论向上还是向下转型,最终都是子类对象做着类型的变化。
向下转型的注意事项:
Animal a = new Dog();
//Cat c = (Cat)a; //向下转型因为不明确具体子类对象类型,所以容易引发ClassCastException异常。
所以为了避免这个问题,需要在向下转型前,做类型判断。
判断类型用的是关键字。instanceof
if(a instanceof Cat) //a指向的对象类型是Cat类型。
{
//将a转型为Cat类型。
Cat a = (Cat)a;
c.catchMouse();
}
else if(a instanceof Dog)
{
Dog d = (Dog)a;
d.lookHome();
}
转型总结
1,什么时候向上转型呢?
提高程序的扩展性,不关心子类型(子类型被隐藏)
需要用子类的特有的方法吗?不需要,那就向上转型。
2,什么时候使用向下转型呢?
需要使用子类特有的方法时。
但是一定要使用instaceof 进行类型的判断,避免发生ClassCastException异常
*/
class DogAndCatTest
{
public static void main(String[] agrs)
{
Dog d = new Dog();
method(d);
Cat c = new Cat();
method(c);
}
public static void method(Animal a)
{
a.eat();
}
}
【15-2】面向对象-多态-举例
//多态-举例
class 毕姥爷
{
public void 讲课()
{
System.out.println("讲管理");
}
public void 钓鱼()
{
System.out.println("钓鱼");
}
}
class 毕老师 extends 毕姥爷
{
public void 讲课()
{
System.out.println("Java");
}
public void 看电影()
{
System.out.println("看电影");
}
}
class DuoTaiTest
{
public static void main(String[] args)
{
毕姥爷 x = new 毕老师();
x.讲课();
x.钓鱼();
//x.看电影();//不行
//想要使用毕老师的特有方法时,需要
if(x instanceof 毕老师)
{
毕老师 y = (毕老师)x;
y.看电影();
}
}
}
-----------------------------------------
【15-3】面向对象-多态-练习-笔记本电脑
=========================================================================================================
//描述笔记本,用到了鼠标的功能。
class noteBook
{
public void run()
{
System.out.println("notebook run");
}
public void useMouse(Mouse m)
{
if(m!=null)
{
m.open();
m.close();
}
}
}
//描述鼠标。
class Mouse
{
public void open()
{
System.out.println("mouse open");
}
public void close()
{
System.out.println("mouse close");
}
}
class NoteTest
{
public static void main(String[] args)
{
noteBook b = new noteBook();
b.run();
b.useMouse(new Mouse());
}
}
==========================================================================================
/*
阶段一需要,笔记本电脑运行。
按照面向对象的思想,用代码体现。
名称提炼法。
笔记本电脑。
行为,运行。
class HoteBook
{
//运行功能
public void run()
{
System.out.println("notebook run");
}
}
阶段二需求:想要在笔记本电脑上加上一个手提式鼠标。
多了个对象,鼠标。
行为:开启,关闭。
class Mouse
{
public void open()
{
System.out.pritnln("mouse open");
}
public void close()
{
System.out.println("mouse close");
}
}
//笔记本怎么用这鼠标呢?
在笔记本中多一个使用鼠标的功能.
需要修改原来的笔记本类中的内容,添加一个功能。
class NoteBook
{
//运行功能
public void run()
{
System.out.println("notebook run");
}
//使用鼠标的功能
public void useMouse(Mouse m)
{
if(m!=null)
{
m.open();
m.close();
}
}
}
//如果想要加入键盘呢?
*/
class Mouse
{
public void open()
{
System.out.println("mouse open");
}
public void close()
{
System.out.println("mouse close");
}
}
class NoteBook
{
//运行功能
public void run()
{
System.out.println("notebook run");
}
//使用鼠标的功能
public void useMouse(Mouse m)
{
if(m!=null)
{
m.open();
m.close();
}
}
}
class DuoTaiTest2
{
public static void main(String[] args)
{
NoteBook book = new NoteBook();
book.run();
book.useMouse(new Mouse());
}
}
--------------------------------------------
【15-4】面向对象-多态-成员变量&成员函数&静态函数的特点
===================================================================================================
/*
多态中,成员调用的特点。
1,成员变量。
当子父类中出现了同名的成员变量时,
多态调用该变量时。
编译时期,参考的是引用变量所属的类中是否有被调用的成员变量,没有,编译失败。
运行时期,也是调用引用变量所属的类中的成员变量。
简单记:编译和运行都参考等号左边
编译运行看左边
2,成员函数。
编译,参考左边,如果没有,编译失败。
运行,参考右边的对象所属的类。
编译看左边,运行看右边。如果子类没有和父类同名的那个函数,则运行的是父类的那个函数。
对于成员函数是动态绑定对到对象上。
3,静态函数。
对于静态成员函数,编译和运行都参考左边。
对于静态函数是静态的绑定到类上。
*/
//结论:
//对于成员变量和静态函数,编译和运行都看左边。
//对于成员函数,编译看左边,运行看右边。
class Fu
{
int num = 3;
void show()
{
System.out.println("fu show run");
}
static void method()
{
System.out.println("fu static method run");
}
}
class Zi extends Fu
{
int num = 5;
void show()
{
System.out.println("zi show run");
}
static void method()
{
System.out.println("zi static method run");
}
}
class DuoTaiDemo
{
public static void main(String[] args)
{
/*
//测试成员变量的多态调用
Fu f = new Zi();
System.out.println(f.num); //3
Zi z = new Zi();
System.out.println(z.num); //5
*/
/*
//测试成员变量的多态调用
Fu f = new Zi();
f.show(); //结果:zi show run;
*/
//测试静态函数的多态调用。
Fu f = new Zi();
f.method();
//注意:真正开发静态方法是不会被多态调用的,因为静态方法不所属于对象,而是所属于类的。
Fu.method();
}
}
来源:https://www.cnblogs.com/sun-/p/5208791.html