码迷,mamicode.com
首页 > 编程语言 > 详细

黑马程序员——java基础--多态

时间:2014-11-27 23:41:12      阅读:323      评论:0      收藏:0      [点我收藏+]

标签:黑马程序员   java基础   多态   

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

模板方法设计模式:
解决的办法:当功能内部一部分是现实确定,一部分是现实不确定的,这时间不可把不确定的部分暴漏出去,让子类实现。
实例:统计一个程序的的运行时间
思路:程序的结束时间减去程序的开始时间

abstract class Gettime{
	public final void getTime(){//这段功能用final限制
		long start = System.currentTimeMillis();
		runtime();//这部分功能不确定,提取出来,通过抽象方法实现
		long end = System.currentTimeMillis();
		System.out.println("te time:"+(end-start));
	}
	public abstract void runtime();//抽象不确定的功能,让子类复写实现
}
class Demo extends Gettime{
	public void runtime(){//子类复写功能方法
		for(int i=0; i<1000; i++){
			System.out.println(i);
		}
	}
}

接口:
1.用interface关键字修饰
2.接口中包含的成员,最常见的有全局变量,抽象方法
注意:接口中的成员都有固定的修饰符
成员变量:public static final
成员方法:public abstract
interface inter{
public static final int x = 3;
publicabstract void show();
}
3.接口中有抽象方法,说明接口中不可实例化,接口的子类必须实现了接口中所有的抽象方法后,该子类才可以实例化,否则,该子类还是一个抽象类。
4.类与类之间存在的是继承关系,类与接口中间存在的是实现关系
继承用extends
实现用implements
5.接口和类不一样的地方就是接口可以被多实现,这就是多继承改良后的结果,java将多继承机制通过多实现来体现

class A{
	void show(){
		System.out.println("a");
	}
}
class B{
	int num = 3;
	void print(){
		System.out.println(num);
	}
}
class C extends A,B{//这样是错误的,类不能多继承,之前提到过
	}
但是可以通过接口的多实现来体现:
abstract class A{
	public abstract void show(){
		System.out.println("a");
	}
}
abstract class B{
	public static final int num = 3;
	public abstract void print(){
		System.out.println(num);
	}
}
class C implements A,B{//这样正确的
	}
6.一个类在继承类一个类的同时,还可以实现多个接口,所以接口的出现避免了单继承的局限性,还可以将类进行功能的扩展。
 class A{
	public void show(){
		System.out.println("a");
	}
}
ieterface class B{
	public static final int num = 3;
	public abstract void print(){
		System.out.println(num);
	}
}
class C extends A implements B{
//这样是可以的,既继承了一个类,也通过接口扩展了功能
}
7.其实java中是有多继承的,只是接口之间存在着多继承关系,接口可以多继承接口,其他的事没有这个属性的
接口都用在设计上,设计的特点:
1.接口是对外提供的规则
2.接口是对功能的扩展
3.接口的出现降低了耦合性
抽象类和接口:
抽象类:一般用于描述一个体系单元,将一组共性内容进行抽取,特点:可以在类中定义抽象内容让子类实现,可以定义非抽象内容让子类直接使用,它里面定义的都是一些体系的基本内容。
接口:一般用于定义对象的扩展功能,而是在继承之外还需对这个对象具备一些功能。
对象和接口的共性:都是不断向上抽取的结果


抽象类与接口的区别:
1.抽象类只能被继承,而且只能被单继承。
接口需要被实现,而且可以被多实现
2.抽象类中可以定义非抽象方法,子类可以直接进行继承使用。
接口中都有抽象方法,需要子类去实现
3.抽象类使用的是 is a 的关系
接口使用的是like a关系
4.抽象类的成员修饰符可以自定义
接口中的成员修饰符是固定的,全部都是public
接口降低了直接耦合性!
接口举例:

class person{
	 void sleep(){
		System.out.println("在床上睡");
	}//这是共性
}
interface class inter{
	abstract void smoking();//这是特性
	abstract void drink();//这是特性,这也可以独立成一个接口
}
class smallstudent extends person{
}
class bigstudent extends person inplememts{
	 smoking(){
		System.out.println("smooking");
	}
	drink(){
		System.out.println("drinking");
	}
}
	
public class interDemo{
	public static void main(String args[]){
		smoking s = new smoking();
		System.out.println(s);
	}
}
多态:
体现:父类引用或者接口的引用指向了自己的子类对象
父类的引用指向了自己的子类对象。
父类的引用也可以接收自己的子类对象//Animal cat = new Cat();
多态的好处:提高了代码的扩展性
多态的弊端:当父类引用子类对象时,虽然提高了扩展性,但是只能访问父类具备的方法,不可以访问子类中特有的方法(前期不能使用后期产生的功能,及访问局限性)
多态的前提:
1.必须要有关系,比如继承或者实现
2.通常会有覆盖操作
多态的实现思想上也做着变化:以前是创建对象并指挥对象做事情,有了堕胎以后,我们可以找到对象的共性类型,直接操作共性类型做事情即可,这样可以指挥一批对象做事情,即通过操作父类或接口实现


多态:可以理解为事物存在的多种体现形态。
人:男人,女人
动物:猫,狗。
猫 x = new 猫();
动物 x = new 猫();

abstract class Animal{
	abstract void sleep();//共性功能
}
class Cat extends Animal{
	sleep(){
		System.out.println("morning sleep");
	}
	public void catchMouse(){//单独属性
		System.out.println("catchMouse");	
	}
}
class Dog extends Animal{
	sleep(){
		System.out.println("night sleep");
	}
	public void yaoren(){
		System.out.println("yaoren");
	}
}
public class duotaiDemo{
	public static void main(String agrs[]){
		Cat c = new Cat();
		c.sleep();
		c.catchMouse();
		Dog d = new Dog();
		d.sleep();
		d.yaoren();
	}//这样是ok的,但是扩展性比较差,因为猫和狗都是动物,他们有共性的属性,		//在创建对象的时候可以使用Animal创建,并且如果有新的动物加进来的话操作更加麻烦
	public static void function(Cat c){
		c.sleep();
	}
	public static void function(Dog d){
		d.sleep();
	}
}
我们可以这样考虑,
	public static void function(Cat c){
		c.sleep();
	}
	public static void function(Dog d){
		d.sleep();
	}
将这段代码简化:
 	public static void function(Animal A){//这里的Animal A = new Cat()/Dog()
		A.sleep();
	}
main函数可以这样写:
public class duotaiDemo{
	public static void main(String agrs[]){
		function(new Cat);
		A.sleep();
		A.catchMouse();
		function(new Dog);
		A.sleep();
		A.yaoren();
	}
}
实例二:
class A{
	void learn(){
		System.out.println("learn chinese");
	}
	void habit(){
		System.out.println("play pingpang");
	}
}
class B extends A{
	void learn(){
		System.out.println("learn english");
	}
	void write(){
		System.out.println(" write code");
	}
}
class Demo{
	public static void main(String args[]){
		A a = new B();//向上转型
		a.learn();
		a.write();//这是错的,父类没有子类的功能
	
		//如果想要调用猫的特有方法时,如何操作?
		//强制将父类的引用。转成子类类型。向下转型。
		B b = (B)a;//向下转型
		b.write();
		//千万不要出现这样的操作,就是将父类对象转成子类类型。
		//我们能转换的是父类应用指向了自己的子类对象时,该应用可以被提升,也可以被强制转换。
		//多态自始至终都是子类对象在做着变化。
	}
}
涉及知识点:向上转型和向下转型
instanceof : 用于判断对象的类型。 对象 intanceof 类型(类类型 接口类型)  
Student instanceof person = true;//student继承了person类
多态在子父类中的成员上的体现特点:
1.成员变量:再多太重,子父类成员变量同名
在编译时期:参考的是引用型变量所属的累中是否有调用的成员
运行时期:也是参考引用型变量所属的类中是否调用的成员
简单一句话:不论编译还是运行,成员变量参考的都是引用变量所属类中的成员变量
也就是:编译运行都看左边
2.成员函数
编译时期:参考引用型变量所属的累中是否有调用地方
运行时期:参考的是对象所属的累中是否有调用的方法
为什么是这样呢?因为在子父类中,对于一摸一样的成员函数,有一个特性:覆盖
简单一句话:成员函数,编译看引用型变量所属的类,运行看对象所属的类
也就是:成员函数编译看左边,运行看右边
3.静态函数:
编译时期:参考的是引用型变量所属的类中是否有调用的成员
运行时期:也是参考引用型变量所属的类中是否有调用的成员
为什么这样呢?因为静态方法不属于对象,而是属于该方法所在的类
简单说:静态函数便已运行都看左边

package code;
class fu{
	int num = 4;
	void show(){
		System.out.println("fu");
	}
	void print(){
		System.out.println("num:"+num);
	}
	public static void method(){
		System.out.println("fu.method");
	}
}
class zi extends fu{
	int num = 5;
	void show(){
		System.out.println("zi");
	}
	public static void method(){
		System.out.println("zi.method");
	}
}
public class duotaiDemo {
	public static void main(String args[]){
		fu a = new zi();
		a.show();//zi
		a.print();//num:4
		a.method();//fu.method
	}
}
总结:成员变量运行结果看左边
成员函数运行结果看右边
静态函数运行结果看左边

实例:主板
分析:电脑有了主板就能运行起来,可以上网,听音乐等,但是这些功能是主板布具备的,只能通过外在的网卡和声卡来扩展,为了提高扩展性,就得需要有个插槽,PCI。
1.可以在主板上使用PCI,然后利用PCI来扩展网卡和声卡功能
2.网卡和声卡自己定义自己的功能
3.完成

class mainboard(){
	mainopen(){
		System.out.println("mainopen");
	}
	mainclose(){
		system.out.println("mainclose");
	}
	mainusepci(pci p){
		if(pci != null){
		p.open();
		p.close();
	}
}
interface pci{
	public abstract void open();
	public abstract void close();
}
class netcard implements pci{
	public void open(){
		System.out.println("netcard open");
	}
	public void close(){
		System.out.println("netcard close");
	}
}
class soundcard implements pci{
	public void open(){
		System.out.println("soundcar open");
	}
	public void close(){
		System.out.println("soundcar close");
	}
}
public class mainboardDemo{
	public static void main(String args[]){
		mainboard m = new mainboard();
		m.open();
		m.mainusepci(new netcard());
		m.mainusepci(new soundcard());
	}
}

Object:是所有对象的直接后者间接父类帝。
该类中定义的肯定是所有对象都具备的功能。
Object类中已经提供了对对象是否相同的比较方法。
如果自定义类中也有比较相同的功能,没有必要重新定义。
只要沿袭父类中的功能,建立自己特有比较内容即可,这就是覆盖.

涉及知识点:
	1.equals
	2.instanceof
	3.tostring()
	4.object类
比较两个对象:
class Demo{
	void show(){
		System.out.println("Demo");
	}
}
class objectDemo{
	public static vodi main(String args[]){
	Demo d1 = new Demo();
	Demo d2 = new Demo();
	System.out.println(d1.equals(d2));//输出false,因为d1和d2地址不一样
	//equals用法:d1.equals(d2)
	}
}
比较两个成员变量:
class Demo{
	private int  num = 4;
	Demo(int num){
		this.num = num;
		}
	public boolean equals(object obj){
		Demo d = (Demo)obj;
		return this.num == d.num;
		}
}
class objectDemo{
	public static vodi main(String args[]){
		Demo d = new Demo();
		
	}
}



黑马程序员——java基础--多态

标签:黑马程序员   java基础   多态   

原文地址:http://blog.csdn.net/orangeisnotapple/article/details/41557933

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!