—————————— ASP.Net+Android+IOS开发、.Net培训、期待与您交流!——————————
多态:
某一些事物的多种表现形态
例如人(Person): 男人(man),女人(women)
例如动物(Animal):猫(cat),狗(dog)
1.多态的体现
父类的引用指向了子类对象
2.多态的前提
必须是类与类之间有关系,要么继承,要么实现
3.多态的好处:
大大提高了程序的扩展性,通常还有一个前提,存在覆盖
4.多态的弊端:
提高了扩展性,但是不能使用的父类的引用访问父类中的成员
Animal a=new Cat(); //类型转换 向上转换
如果想要调用猫的特有方法时,如何操作?
可以强制将父类的引用,转成子类类型,向下转型
Cat c=(Cat)a;
c.子类特有方法();
千万别出现这样的操作,将父类的对象转成子类类型,
我们转换的是父类的引用指向自己子类时,该引用可被提升
,也可以被强制转换.
Animal a=new Animal();
Cat c=(Cat)a; //这样是错误的
多态自始至终都是子类对象做着变化
instanceOf关键字:
判断某一些类型引用是否指向某一些类型
例如 a instanceOf Cat
5.多态的应用
6.多态的出现代码中的特点(多态使用注意事项):
在多态中非静态成员函数的特点(父类引用指向了子类对象):
在编译时期,参阅引用类型变量所属类中是否有该方法,有侧编译通过,
否则,编译失败.
简而言之:非静态成员函数在多态中,编译看左边,运行看右边
在多态中成员变量的特点:
无论编译还是运行都是看参考左边(引用类型所属的类)
在多态中静态方法的特点:
无论编译还是运行都参考左边
方法区分静态方法区和非静态方法区
Object
object是所有父类对象直接 或间接的父类
该类中定义的功能肯定所有对象都具备的功能
equals(Object obj)
指示其他某个对象是否与此对象“相等”。
object类中已经提供与对象是否相同的比较功能.
如果自定义类中也有比较相同的功能,没有必要重新定义,
只要沿袭父类中的功能建立自己特有的比较的内容即可,就是覆盖
toString()
返回该对象的字符串表示。通常,toString 方法会返回一个“以文本方式表示”此对象的字符串。
结果应是一个简明但易于读懂的信息表达式。建议所有子类都重写此方法。
hashCode();//object类中的方法, 返回该对象的哈希码值。
Integer.toHexString();//integet类方法 十进制转16进制
getClass(); //obejct方法 返回此 Object 的运行时类。
class文件运行一进内存,类就被封装成对象,所以有一个Class类描述这些class文件
Class中有这些class对象的共性方法,例如名称,一般方法,构造函数
方法:
getName();
以 String 的形式返回此 Class 对象所表示的实体(类、接口、数组类、基本类型或 void)名称。
—————————— ASP.Net+Android+IOS开发、.Net培训、期待与您交流!——————————
多态:
某一些事物的多种表现形态
例如人(Person): 男人(man),女人(women)
例如动物(Animal):猫(cat),狗(dog)
1.多态的体现
父类的引用指向了子类对象
2.多态的前提
必须是类与类之间有关系,要么继承,要么实现
3.多态的好处:
大大提高了程序的扩展性,通常还有一个前提,存在覆盖
4.多态的弊端:
提高了扩展性,但是不能使用的父类的引用访问父类中的成员
Animal a=new Cat(); //类型转换 向上转换
如果想要调用猫的特有方法时,如何操作?
可以强制将父类的引用,转成子类类型,向下转型
Cat c=(Cat)a;
c.子类特有方法();
千万别出现这样的操作,将父类的对象转成子类类型,
我们转换的是父类的引用指向自己子类时,该引用可被提升
,也可以被强制转换.
Animal a=new Animal();
Cat c=(Cat)a; //这样是错误的
多态自始至终都是子类对象做着变化
instanceOf关键字:
判断某一些类型引用是否指向某一些类型
例如 a instanceOf Cat
5.多态的应用
/*
多态的应用 例子一
基础班学生: 学习 睡觉
高级班学生: 学习 睡觉(坐着睡觉)
可以将这两类事物向上抽取,发现功能定义相同,内容不同
*/
class Demo1
{
public static void main(String[] args)
{ /*
Student s=new AdvStudent();
s.study();
s.sleep();
s.function(); //错误的, 编译时看父类引用是否有该方法
*/
method(new BaseStudent());
method(new AdvStudent());
}
public static void method(Student ss){
ss.study();
ss.sleep();
/*使用子类的特有方法要进行判断,进行强制向下转换*/
if(ss instanceof BaseStudent){
BaseStudent s=(BaseStudent)ss;
}else if(ss instanceof AdvStudent){
AdvStudent a=(AdvStudent)ss;
a.function();
}
}
}
abstract class Student
{
public abstract void study();
public void sleep(){
System.out.println("躺着睡觉");
}
}
class BaseStudent extends Student
{
public void study(){
System.out.println("学习基础知识");
}
}
class AdvStudent extends Student
{
public void study(){
System.out.println("学的就业知识");
}
public void sleep(){
System.out.println("哥们是站着睡的");
}
public void function(){
System.out.println("哥有自己的特有方法");
}
}
/*
多态的应用 例子二
接口多态
主板的运行示例
*/
class Demo3
{
public static void main(String[] args)throws Exception
{
MainBoard mb=new MainBoard();
mb.run();
mb.userPCI(new NetCard());//网卡
mb.userPCI(new SoundCard());//声卡
//三秒主板关闭,电脑结束运行
Thread.sleep(3000);
mb.close();
}
}
/*主板类*/
class MainBoard
{
public void run(){
System.out.println("主板开启了");
}
public void reset(){
System.out.println("主板重启了");
}
public void close(){
System.out.println("主板关闭了");
}
public void userPCI(PCI p){ //实现PCI扩展功能
p.open();
p.close();
}
}
/*网卡,声卡等PCI卡槽*/
interface PCI
{
public abstract void open();
public abstract void close();
}
/*网卡 实现PCI卡槽同一标准f*/
class NetCard implements PCI
{
public void open(){
System.out.println("网卡开启");
}
public void close(){
System.out.println("网卡关闭");
}
}
/*声卡卡 实现PCI卡槽同一标准f*/
class SoundCard implements PCI
{
public void open(){
System.out.println("声卡开启");
}
public void close(){
System.out.println("声卡关闭");
}
}
/*
数据库操作 例子三
假如本来使用jdbc对数据进行操作,然后改用框架高级操作了
只要修改BaseDao的连接 关闭方法即可,
Data Access Object DAO
此代码不准备运行
*/
class Demo4
{
public static void main(String[] args)
{
new UserDaoImple();// 调用方法进行传参即可
}
}
class EntityDao
{
private int age;
public void setAge(int age){
this.age=age;
}
public int getAge(){
return age;
}
}
class BaseDao
{
//使用jdbc链接数据库
//关闭数据库链接
}
interface UserDao
{
public void add(EntityDao e);
}
class UserDaoImpl implements UserDao
{
public void add(EntityDao e){
BaseDao.开启数据库();
//执行add 操作
//Base.closeAll(con,pst,rs); 关闭全部
}
}
6.多态的出现代码中的特点(多态使用注意事项):
在多态中非静态成员函数的特点(父类引用指向了子类对象):
在编译时期,参阅引用类型变量所属类中是否有该方法,有侧编译通过,
否则,编译失败.
简而言之:非静态成员函数在多态中,编译看左边,运行看右边
在多态中成员变量的特点:
无论编译还是运行都是看参考左边(引用类型所属的类)
在多态中静态方法的特点:
无论编译还是运行都参考左边
方法区分静态方法区和非静态方法区
/*
多态出先在成员中的特点
*/
class Demo2
{
public static void main(String[] args)
{
/*
编译时期看父类,运行就运行子类的
这个是可以的
Test1 t=new Test2();
t.method_1();
t.method_2();
*/
/*
//编译时期看父类,运行就运行子类的
//这个是不可以的
Test1 t=new Test2();
t.method_1();
t.method_2();
t.method_3(); //父类没有这个方法,编译出错
*/
/*
//要上诉的编译运行,需要进行强制转换
Test1 t=new Test2();
t.method_1();
t.method_2();
Test2 t2=(Test2)t;
t2.method_3();
*/
//new Test3().method_3(); //final方法可以被继承,不能覆盖
//静态成员变量,非静态成员变量,静态方法编译运行都是看左边
Test1 t= new Test2();
System.out.println(t.num); //输出的父类引用的num值 即使是static所修饰的
t.method_4(); //static函数输出的也是父类的内容
System.out.println(t.getN());//没有重写输出的是父类的
}
}
/*
父类 test1
*/
abstract class Test1
{
static int num=3;
private int n=50;
public int getN()
{
return n;
}
public abstract void method_1();
public void method_2(){
System.out.println("fu method_2");
}
public static void method_4(){
System.out.println("fu static");
}
}
/*
test2 继承 test1
*/
class Test2 extends Test1
{
static int num=30;
private int n=5;
/*
//如果重写getN() 那么获取就是本类的
public int getN()
{
return n;
}
*/
public void method_1(){
System.out.println("zi method_1");
}
public final void method_3(){
System.out.println("zi method_3");
}
public static void method_4(){
System.out.println("zi static");
}
}
/*测试类*/
class Test3 extends Test2
{
}
Object
object是所有父类对象直接 或间接的父类
该类中定义的功能肯定所有对象都具备的功能
equals(Object obj)
指示其他某个对象是否与此对象“相等”。
object类中已经提供与对象是否相同的比较功能.
如果自定义类中也有比较相同的功能,没有必要重新定义,
只要沿袭父类中的功能建立自己特有的比较的内容即可,就是覆盖
toString()
返回该对象的字符串表示。通常,toString 方法会返回一个“以文本方式表示”此对象的字符串。
结果应是一个简明但易于读懂的信息表达式。建议所有子类都重写此方法。
hashCode();//object类中的方法, 返回该对象的哈希码值。
Integer.toHexString();//integet类方法 十进制转16进制
getClass(); //obejct方法 返回此 Object 的运行时类。
class文件运行一进内存,类就被封装成对象,所以有一个Class类描述这些class文件
Class中有这些class对象的共性方法,例如名称,一般方法,构造函数
方法:
getName();
以 String 的形式返回此 Class 对象所表示的实体(类、接口、数组类、基本类型或 void)名称。
class Demo5
{
public static void main(String[] args)
{
One one=new One();
one.setNum(4);
Two two=new Two();
two.setNum(4);
Three three=new Three();
three.setNum(5);
System.out.println(one.equals(two));
//System.out.println(one.euqals(three));//编译通过,运行异常
//直接或间接之类都拥有object类的功能,不复写一样可以equals
System.out.println(three.equals(two));
System.out.println(two.toString());
System.out.println(three.toString());
}
}
/*
one类要有一个比较的方法,直接复写equals即可
*/
class One
{
private int num;
public void setNum(int num){
this.num=num;
}
public int getNum(){
return num;
}
/*复写equals 比较两个对象的num属性时候相同*/
public boolean equals(Object obj){
if(!(obj instanceof Two))
throw new RuntimeException("传入对象类型失败");
Two t=(Two)obj;
return this.getNum()==t.getNum();
}
}
class Two
{
private int num;
public void setNum(int num){
this.num=num;
}
public int getNum(){
return num;
}
}
class Three
{
private int num;
public void setNum(int num){
this.num=num;
}
public int getNum(){
return num;
}
/*复写 toString*/
public String toString(){
return this.getClass().getName()+"@"+Integer.toHexString(this.hashCode());
}
}
—————————— ASP.Net+Android+IOS开发、.Net培训、期待与您交流!——————————