多态:可以理解为事物存在的多种体现形态。
人:男人 女人
动物:猫 狗
猫 x=new 猫();
动物 x=new 猫();
1、多态的体现
父类的引用指向了自己的子类对象
父类的引用也可以接受自己子类的对象
2、多态的前提
必须是类与类之间有关系。要么继承,要么实现。
通常还有一个前提:存在覆盖
3、多态的好处
多态的出现大大的提高了程序的扩展性
4、多态的弊端
提高了扩展性,但是只能使用父类的引用访问父类中的成员。
5、多态的应用
6、多态的出现代码中的特点
class Animal
{
abstractvoid eat();
}
class Cat extends Animal
{
publicvoid eat()
{
System.out.println("吃鱼");
}
publicvoid catchMouse()
{
System.out.println();
}
}
class Dog extends Animal
{
publicvoid eat()
{
System.out.println("吃骨头");
}
publicvoid kanJia()
{
System.out.println("看家");
}
}
class DuoTaiDemo
{
publicstatic void main(String[] args)
{
Animala=new Cat();//类型提升,向上转型。
a.eat();
//如果想要调用特有属性怎么办?
//强制将父类的引用,转成子类类型.向下转型
Catc=(Cat)a;
c.catchMouse();
//千万不要出现这样的操作,就是将父类的对象转成子类类型
//我们能转换的是父类引用指向了自己的子类对象时,该引用可以被提升,也可以被强制转换。
//多态自始至终都是子类对象在做着变化
//Animala=new Animal();
//Catc=(Cat)a;不可以转换
function(newDog());
function(new Cat());
}
publicstatic void function(Animal a)
{
a.eat();
if(a instanceof Cat)//判断对象所属类型instanceof
{
Catc=(Cat)a;
c.catchMouse();
}
}
}
/*
多态的应用
基础班学生:
学习,睡觉。
高级班学生:
学习,睡觉。
可以将这两类事物进行抽取
*/
abstract class Student
{
publicabstract void study();
publicvoid sleep()
{
System.out.println("躺着睡");
}
}
class BaseStudent extends Student
{
publicvoid study()
{
System.out.println("basestudy");
}
publicvoid sleep()
{
System.out.println("站着睡");
}
}
class AdvStudent extends Student
{
publicvoid study()
{
System.out.println("advstudy");
}
}
class DoStudent
{
publicvoid doSome(Student stu)
{
stu.study();
stu.sleep();
}
}
class DoTaiDemoTest
{
publicstatic void main(String[] args)
{
DoStudentds=new DoStudent();
ds.doSome(newBaseStudent());
ds.doSome(newAdvStudent());
}
}
class Fu
{
intnum=5;//面试题
voidmethod1()
{
System.out.println("fumethod_1");
}
voidmethod2()
{
System.out.println("fumethod_2");
}
staticvoid method4()//面试题
{
System.out.println("fumethod_4");
}
}
class Zi extends Fu
{
intnum=8;//面试题
voidmethod1()
{
System.out.println("zimethod_1");
}
voidmethod3()
{
System.out.println("zimethod_3");
}
staticvoid method4()//面试题
{
System.out.println("zimethod_4");
}
}
class DuoTaiDemo2
{
publicstatic void main(String[] args)
{
Fuf=new Zi();
System.out.println(f.num);//运行结果是父类中的变量5
面试题:
在多态中,成员变量的特点:
无论编译和运行,都参考左边(引用型变量所属的类)。
f.method4();//结果是父类中的静态方法执行,因为静态依存于类,不参考对象
面试题:
在多态中,静态成员函数的特点:
无论编译和运行,都参考左边
Fuf=new Zi();
f.method1();
f.method2();
//f.method3();编译错误
在多态中成员函数的特点:
在编译时期:参阅引用型变量所属的类中是否有调用的方法。如果有,编译通过,如果没有,编译失败
在运行时期:参阅对象所属的类中是否有调用的方法。有则运行。
简单总结就是:成员函数在多态调用时,编译看左边,运行看右边。
}
}
电脑主板多态和接口练习:
/*
需求:
电脑运行实例
电脑运行基于主板
*/
class MainBoard
{
publicvoid run()
{
System.out.println("mainboardrun");
}
publicvoid usePCI(PCI p)//PCI p=new NetCard 接口型引用指向自己的子类对象
{
if(p!=null){
p.open();
p.close();
}
else
System.out.println("NO");
}
}
interface PCI
{
publicvoid open();
publicvoid close();
}
class NetCard implements PCI
{
publicvoid open()
{
System.out.println("netcardopen");
}
publicvoid close()
{
System.out.println("netcardclose");
}
}
class SoundCard implements PCI
{
publicvoid open()
{
System.out.println("soundCardopen");
}
publicvoid close()
{
System.out.println("soundCardclose");
}
}
class DuoTaiDemo5
{
publicstatic void main(String[] args)
{
MainBoardmb=new MainBoard();
mb.run();
mb.usePCI(null);
mb.usePCI(newNetCard());
mb.usePCI(newSoundCard());
}
}
多态扩展实例:
需求:数据库的操作
数据是:用户信息
1、连接数据库 JDBC Hibernate
2、操作数据库。
c create r read u update d delete
3、关闭数据库连接。
interface UserInfoDao
{
publicvoid add(User user);
publicvoid delete(User user);
}
class UserInfoByJDBC implementsUserInfoDao
{
publicvoid add(User user)
{
1、连接数据库。
2、使用sql添加语句添加数据,
3、关闭连接
}
publicvoid delete(User user)
{
1、连接数据库。
2、使用sql添加语句删除数据,
3、关闭连接
}
}
class UserInfoByHibernate implementsUserInfoDao
{
publicvoid add(User user)
{
1、连接数据库。
2、使用sql添加语句添加数据,
3、关闭连接
}
publicvoid delete(User user)
{
1、连接数据库。
2、使用sql添加语句删除数据,
3、关闭连接
}
}
class DBOperate
{
publicstatic void main(String[] args)
{
UserInfoDaoui=new UserInfoByJDBC();
ui.add(user);
ui.delete(user);
}
}
Object类 equals和toString练习:
object:是所有对象的直接后者间接父类,传说中的上帝。
该类中定义的肯定是所有对象都具备的功能
object类中已经提供了对对象是否相同的比较方法。equals
如果自定义类中也有比较相同的功能,没有必要重新定义。
只要沿袭父类的功能,建立自己特有比较内容即可,这就是覆盖。
class Demo//extends Object
{
privateint num;
Demo(intnum)
{
this.num=num;
}
publicboolean equals(Object obj)//Object obj=new Demo();复写
{
if(!(objinstanceof Demo))//判断是否是同一类型,不同类型不可以比
returnfalse;
Demod=(Demo)obj;//多态,向下转型
returnthis.num==d.num;
}
publicString toString()//自己的toString方法,覆盖
{
return"demo:"+num;
}
}
class Person
{
}
class ObjectDemo
{
publicstatic void main(String[] args)
{
Demod1=new Demo(4);
Demod2=new Demo(4);
//Personp=new Person();
Classc=d1.getClass();
System.out.println(c.getName()+"@@"+Integer.toHexString(d1.hashCode()));
System.out.println(d1.toString());
//System.out.println(d1.equals(p));
}
}
我的总结:明确面向对象的第三个特征多态,知道多态的特点和使用。特别注意多态在成员变量、静态成员函数和成员函数中编译和运行的特点。了解object类。
通过小题目了解向上转型和向下转型:
class A
{
String a="class A";
}
class B extends A
{
String b="class B";
}
class E
{
public static void main(String[] args)
{
A a1,a2=new A();
B b1,b2=new B();
a1=b2;
b1=(B)a1;
b2=(B)a2;//A cannot be cast to B
System.out.println(a1.a);
System.out.println(b1.b);
}
}