多态概述
什么是多态
多态即事物可以有多种存在形态,如:猫可以是猫类也可以是动物类
代码示例
Cat cat
=new Cat();
Animal animal
=new Cat();
多态的体现
父类引用指向子类对象,通俗来说就是父类引用可以指向自己的对象
public void static main(String
[] args
){
function(new Cat());
function(new Dog());
}
public static void function(Animal a
)
{
a
.eat();
}
多态的好处
提高了程序的扩展性,使得同一个函数得以复用,方便后续开发的扩展
使用多态的前提
必须是类与类之间有继承(extends)或者实现关系(写一个接口让另一个类implement)存在对父类的覆盖
多态的弊端
只能使用父类引用访问父类成员,即cat继承Animal类并且覆盖Animal的eat或者相关方法。
多态的转型
Animal a
=new Cat();
if(a
instanceof Cat )
Cat c
=(Cat
)a
;
多态的案例
需求
普通学生和2b学生都是有各自的方式学习,但是普通学生躺着睡,2b学生站着睡,请使用多态的方法完成上述功能,注意该程序还得具有可扩展性以及函数的相关复用性。
代码
bstract
class Student
{
public abstract void study();
public void sleep()
{
System
.out
.println("躺着睡");
}
}
class DoStudent
{
public void doSome(Student stu
)
{
stu
.study();
stu
.sleep();
}
}
class StupidStudent extends Student
{
public void study()
{
System
.out
.println("base study");
}
public void sleep()
{
System
.out
.println("站着睡");
}
}
class AdvStudent extends Student
{
public void study()
{
System
.out
.println(" adv study");
}
}
class Test
{
public static void main(String
[] args
)
{
DoStudent ds
= new DoStudent();
ds
.doSome(new StupidStudent());
ds
.doSome(new AdvStudent());
}
}
多态的常见面试题
成员函数在多态调用时,编译看左边,运行看右边
在多态中成员函数的特点: 在编译时期:参阅引用型变量所属的类中是否有调用的方法。如果有,编译通过,如果没有编译失败。 在运行时期:参阅对象所属的类中是否有调用的方法。
class Fu
{
static int num
= 5;
void method1()
{
System
.out
.println("fu method_1");
}
void method2()
{
System
.out
.println("fu method_2");
}
static void method4()
{
System
.out
.println("fu method_4");
}
}
class Zi extends Fu
{
void method1()
{
System
.out
.println("zi method_1");
}
void method3()
{
System
.out
.println("zi method_3");
}
static void method4()
{
System
.out
.println("zi method_4");
}
}
class Test
{
public static void main(String
[] args
)
{
Fu f
=new Zi();
f
.method1();
f
.method2();
}
}
成员变量编译和结果全都取决于引用类型
class Fu
{
static int num
= 5;
}
class Zi extends Fu
{
static int num
= 8;
}
class Test
{
public static void main(String
[] args
)
{
Fu f
= new Zi();
System
.out
.println(f
.num
);
Zi z
= new Zi();
System
.out
.println(z
.num
);
}
}
静态函数编译运行全看引用类型
class Fu
{
static void method4()
{
System
.out
.println("fu method_4");
}
}
class Zi extends Fu
{
static void method4()
{
System
.out
.println("zi method_4");
}
}
class Test
{
public static void main(String
[] args
)
{
Fu f
= new Zi();
f
.method4();
Zi z
= new Zi();
z
.method4();
}
}
图解代码运行原理
如下图,静态区存储的是对象而不是this和spuer关键字,所以在使用静态方法的时候加入引用对象为fu则使用fu的static函数
多态实现主板扩展功能
需求
实现电脑插入网卡、声卡、功能上还要求方便拓展
需求图解
interface PCI
{
public void open();
public void close();
}
class MainBoard
{
public void run()
{
System
.out
.println("mainboard run ");
}
public void usePCI(PCI p
)
{
if(p
!=null
)
{
p
.open();
p
.close();
}
}
}
class NetCard implements PCI
{
public void open()
{
System
.out
.println("netcard open");
}
public void close()
{
System
.out
.println("netcard close");
method();
}
}
class SoundCard implements PCI
{
public void open()
{
System
.out
.println("SoundCard open");
}
public void close()
{
System
.out
.println("SoundCard close");
}
}
class Test
{
public static void main(String
[] args
)
{
MainBoard mb
= new MainBoard();
mb
.run();
mb
.usePCI(new NetCard());
mb
.usePCI(new SoundCard());
}
}
多态实现数据库操作
使用jdbc连接数据库操作,但是后期有可能改为其他操作框架,这时我们就需在设计上考虑降低耦合性
图解
如下图所示,由于使用接口作为标准,多态的实现接口,即使修改操作框架,我们也只需修改ui的指向即可
代码
interface UserInfoDao
{
public void add(User user
);
public void delete(User user
);
}
class UserInfoByJDBC implements UserInofDao
{
public void add(User user
)
{
1,JDBC连接数据库。
;
2,使用sql添加语句添加数据。
;
3,关闭连接。
}
public void delete(User user
)
{
1,JDBC连接数据库。
;
2,使用sql添加语句删除数据。
;
3,关闭连接。
}
}
class UserInfoByHibernate implements UserInfoDao
{
public void add(User user
)
{
1,Hibernate连接数据库。
;
2,使用sql添加语句添加数据。
;
3,关闭连接。
}
public void delete(User user
)
{
1,Hibernate连接数据库。
;
2,使用sql添加语句删除数据。
;
3,关闭连接。
}
}
class DBOperate
{
public static void main(String
[] args
)
{
UserInfoDao ui
= new jdbc或者其他操作框架
;
ui
.add(user
);
ui
.delete(user
);
}
}
object类
概述
Object:是所有对象的直接后者间接父类,传说中的上帝。 该类中定义的肯定是所有对象都具备的功能。
equals和toString
equals方法
比较的是对象的地址空间是否相同
toString方法
输出的是对象的类型+"@"+内存地址的十六进制 Object类中已经提供了对对象是否相同的比较方法。
如果自定义类中也有比较相同的功能,没有必要重新定义。 只要沿袭父类中的功能,建立自己特有比较内容即可。这就是覆盖。
代码
class Demo
{
private int num
;
Demo(int num
)
{
this.num
= num
;
}
public boolean equals(Object obj
)
{
if(!(obj
instanceof Demo))
return false;
Demo d
= (Demo
)obj
;
return this.num
== d
.num
;
}
public String
toString()
{
return "demo:"+num
;
}
}
class Person
{
}
class ObjectDemo
{
public static void main(String
[] args
)
{
Demo d1
= new Demo(4);
System
.out
.println(d1
);
Demo d2
= new Demo(7);
System
.out
.println(d2
.toString());
}
}