1,多态的体现:
父类的引用指向了自己的子类对象
父类的引用也可以接收自己的子类对象
2,多态的前提:
必须是类与类之间有关系,要么继承,要么实现
通常还有一个前提:存在覆盖
3,多态的好处
多态的出现大大的提高程序的扩展性
4,多态的弊端
提高了扩展性,但是只能使用父类的引用访问父类中的成员
5,多态的应用
*/
/*
动物,
猫,狗,猪
*/
abstract class Animal
{
abstract void eat();
}
class Car extends Animal
{
abstract void eat()
{
System.out.println("吃鱼");
}
public void xingwei()
{
System.out.println("抓老鼠");
}
}
class Dog extends Animal
{
abstract void eat()
{
System.out.println("吃骨头");
}
public void xingwei()
{
System.out.println("看家");
}
}
class DuoTaiDemo
{
public static void main(String[] args)
{
//Cat c=new Cat();
//c.eat();
//Dog d=new Dog();
//d.eat();
function(new Car()); //直接调用猫丢在方法里面 方法是吃
function(new Dog());
}
public static void function(Animal a) //简化了代码,因为猫和狗都是动物类所以可以直接用动物代替
{
a.eat();
}
/*
public static void function(Car c)
{
c.eat();
}
public static void function(Car c)
{
c.eat();
}
*/
}
多态的转型:
案例:
class DuoTaiDem2
{
public static void main(String[] args)
{
Animal a=new Cat();//类型提升 向上转型
a.eat();
//如果想要调用,猫的特有方法,如何操作?
//强制将父类的引用,转成子类类型,向下转型,
Cat c=(Cat)a; //注意这时的a是指对象,而对象又指向了Animal
c.xingwei(); //打印猫特有的功能;
//千万不要出现这样的操作,就是将父类对象转成子类类型
//我们能转换的是父类应用指向了自己的子类对象时,该应用可以操作,也可以被强制转换
//多态自始自终都是子类对象在做着变化
// Animal a=new Animal();
// Cat c=(Cat)a;
}
}
function(new Dog());
public static void function(Animal a)
{
a.eat();
if(a instanceof Cat)
{
Cat c=(Cat)a;
c.xingwei();
}
else if(a instanceof Dog)
{
Dog c=(Dog)a;
c.xingwei();
}
}
/*
基础班学生:
学习,睡觉
高级班学生:
学习,睡觉
可以将这两类事物进行抽取
*/
abstract class Student //学员,父类
{
public abstract void study(); //行为是学习,大家学习方法不一样所以是抽象
puclic void sleep() // //行为睡觉
{
System.out.println("躺着睡");
}
}
class BaseStudent extends Student
{
public void study() //普通学员的学习方法
{
System.out.println("base study");
}
public void sleep() //睡觉方法复写了,不想“躺着睡”
{
System,out.println("坐着睡");
}
}
calss AdvStudent extends Student
{
public void study() //高级学员的学习方法
{
System.out.println("adv study");
}
}
class DoStudent
{
public void doSome(Studen stu)
{
stu.study();
stu.sleep();
}
}
class DuoTaiDemo3
{
public static void main(String[] args)
{
DoStuden ds=new Dostudent(); //创建一个对象,用里面的方法
ds.doSome(new BaseStudent()); //将学员的行为丢进这方法中
ds.doSome(new AdvStudent());
//BaseStudent bs=new BaseStudent();
//bs.study();
//bs.sleep();
//AdvStudent as=new AdvStudent();
//as.study();
//as.sleep();
}
}
/*
在多态中非静态成员函数的特点;
在编译时期:参阅引用型变量所属的类中是否有调用的方法,如果有,编译通过,如果没有编译失败
在运行时期:参阅对象所属的类中是否有调用的方法
简单总结就是:成员函数在多态调用时,编译看左边,运行看右边
*/
在多态中,成员变量的特点:
无论编译和运行,都参考左边(引用型变量所属的类)
在多态中,静态成员函数的特点:
无论编译和运行,都参考做左边,
class Fu
{
int num=5;
void method1()
{
System.out.println("fu 1");
}
void method2()
{
System.out.println("fu 2");
}
}
class Zi extends Fu
{
int num=8;
void method1()
{
System.out.println("zi 1");
}
void method3()
{
System.out.println("zi 3");
}
}
class DuoTaiDemo4
{
public static void main(String[] args)
{
Fu f=new Zi();
System.out.println(f.num); //打印的是父的5 因为是成员变量,只看F引用的类
Zi z=new Zi();
System.out.println(z.num); //打印的是子的8 因为是成员变量,只看z引用的类
f.method1();
f.method2();
//f.method3(); //编译出错,因为父类中没有这共享方法
}
}
多态的应用
interface PCI //接口
{
public void oper();
public void close();
}
class MainBoard //主板
{
public void run()
{
System.out.println("mainboard run");
}
public void usePCI(PCI p) //接口型引用指向自己的子类对象
{
if(p!=null) //判断传入的数据不能为空,只有不能为空才能使用功能
p.oper();
p.close();
}
}
class NetCard implements PCI //新出现类声卡
{
public void oper()
{
System.out.println("netcard 开");
}
}
public void close()
{
System.out.println("netcard 关");
}
class DuoTaiDemo5
{
public static void main(String[] args)
{
MainBoar mb=new MainBoard(); //创建一个主板的对象mb
mb.run(); //用自己的方法
mb.usePCI(null); //用自己的方法,发现是指向一个接口,所以接口不能为空
mb.usePCI(new NetCard()); //用自己的方法,发现是指向一个接口,而接口又又指向另一个对象
//所以调用子类中的方法,接口方法被子类复写了,所以没输出
}
}
object:是所有对象的直接或者间接父类,传说中的上帝
该类中定义的肯定是所有对象都具备的功能
需求是:本类对象中自己家成员做对比
class Demo
{
public int num;
Demo(int num)
{
this.num=num;
}
public boolean equals(object obj)
{
if(obj instanceof Demo) //这是判断两个类是否的语句
return false;
Demo d=(Demo)obj; //向下转型是因为父类object中没有定义num这个数
//需要转成子类的才可以对比
return this.num==d.num;
}
}
class ObjectDemo
{
public static void main(String[] args)
{
Demo d1=new Demo(4);
Demo d2=new Demo(5);
System.out.println(d1.equals(d2)); //得出结果是true 或是 false 因为上路是boolean
}
} |
|