黑马程序员--- 学习笔记(第八天)

 —————————— 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培训、期待与您交流!——————————

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值