java基础--多态与包

一 多态:可以理解为事物存在的多种形态

1> 多态的体现

父类的引用指向了自己的子类对象。

父类的引用也可以接收自己的子类对象。

2> 多态的前提:  必须是类与类之间有关系。要么继承,要么实现。

    通常还有一个前提:存在覆盖。

3> 多态的好处:  

多态的出现大大的提高程序的扩展性。

4> 多态的弊端:

 提高了扩展性,但是只能使用父类的引用访问父类中的成员。

5> 多态的应用


 

多态的扩展性代码体现:


 

 

abstract class Animal {
	//各种动物吃的方式不同,抽取方法
	abstract void eat();

}

class Cat extends Animal {
	public void eat() {
		System.out.println("吃鱼");
	}

	public void catchMouse() {
		System.out.println("抓老鼠");
	}
}

class Dog extends Animal {
	public void eat() {
		System.out.println("吃骨头");
	}

	public void kanJia() {
		System.out.println("看家");
	}
}

class Pig extends Animal {
	public void eat() {
		System.out.println("饲料");
	}

	public void gongDi() {
		System.out.println("拱地");
	}
}

// -----------------------------------------

class DuoTaiDemo {
	public static void main(String[] args) {
		// Cat c = new Cat();
		// c.eat();

		// Dog d = new Dog();
		// d.eat();

		// 没有使用多态时,需要根据参数的类型去调用相应的方法
		/*
		 	Cat c1 = new Cat(); 
function(c1); 
function(new Dog()); 
function(new Pig());
		 */

		// 父类的引用指向了自己的子类对象。
		Animal c = new Cat();
		c.eat();

		function(new Cat());
		function(new Dog());
		function(new Pig());

	}

	// 父类的引用也可以接收自己的子类对象。
	// 多态的出现大大的提高程序的扩展性,后期只要传入动物,就可以
	public static void function(Animal a)// Animal a = new Cat();
	{
		a.eat(); // 不同动物已经并复写了eat方法
		// a.catchMouse(); //提高了扩展性,但是只能使用父类的引用访问父类中的成员。

	}

 

 

二  类型转换:

 

只有当转换的父类引用指向自己的子类对象时,该引用可以被提升。

向上转型 Animal a= new Cat();

向下转型Cat c =(Cat)a;

多态自始至终都是子类对象在做着变化

当想使用子类的特有方法时,需要向下转型。

 

注意:

Animal a = new Animal();

Cat c = (Cat)a;       将父类对象转成子类类型,是不可能的,难道只要是动物就能转成猫么?


转型示例:


abstract class Animal{
	public abstract void eat();
}

class Cat extends Animal {
	public void eat() {
		System.out.println("吃鱼");
	}

	public void catchMouse() {
		System.out.println("抓老鼠");
	}
}

class Dog extends Animal {
	public void eat() {
		System.out.println("吃骨头");
	}

	public void kanJia() {
		System.out.println("看家");
	}
}

class Pig extends Animal {
	public void eat() {
		System.out.println("饲料");
	}

	public void gongDi() {
		System.out.println("拱地");
	}
}

// -----------------------------------------

class DuoTaiDemo2 {
	public static void main(String[] args) {
		
		// Animal a = new Cat();//类型提升,向上转型。
		// a.eat();

		// 强制将父类的引用。转成子类类型,向下转型。
		//Cat c = (Cat)a;
		// c.catchMouse();

		/*我们能转换的是父类应用指向了自己的子类对象时,该引用可以被提升,也可以被强制转换。
		多态自始至终都是子类对象在做着变化。
		 	
		下面代码将父类对象转成子类类型,是不可能的,难道只要是动物就能转成猫么?
		Animal a = new Animal();
		Cat c = (Cat)a; 
		*/
		
		function(new Dog());
		function(new Cat());

	}

	public static void function(Animal a)// Animal a = new Cat();
	{
		a.eat();	
		if (a instanceof Cat) {
			Cat c = (Cat) a;
			c.catchMouse();
		} else if (a instanceof Dog) {
			Dog c = (Dog) a;
			c.kanJia();
		}

		/*
		 * instanceof : 用于判断对象的类型。 对象 intanceof 类型(类类型 接口类型)
		 */
	}
}

多态应用:主板与扩展设备的示例



package cn.xushuai.Test;

/*沒有使用接口的情況,每次有新设备都需要定义独立的设备,
 class MainBoard{
 	public void run(){
 		System.out.println("mainboard run");
 	}
 	public void useNetCard(NetCard c){
 		c.open();
 		c.close();
 	}
 }

 class NetCard{
 	public void open(){
 		System.out.println("netcard open");
 }
 	public void close(){
 		System.out.println("netcard close");
 	}
 }
 */

//各种设备的使用规则,只需扩展设备去遵循,实现方法即可,提高了程序的扩展性。
interface PCI {

	public void open();

	public abstract void run();
}

class MainBoard {
	public void userPCI(PCI p) {
		if (p != null) { // 防止空指针异常,检测是否有设备
			p.open();
			p.run();
		}
	}

}

class NetCard implements PCI {

	public void open() {
		System.out.println("网卡 打开正常!");
	}

	public void run() {
		System.out.println("网卡   开始 run.......!");
	}
}

class SoundCard implements PCI {

	@Override
	public void open() {
		System.out.println("声卡 打开正常");
	}

	@Override
	public void run() {
		System.out.println("声卡 开始 run.........!");
	}

}

public class MainBoardDemo {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		MainBoard mb = new MainBoard();
		mb.userPCI(new SoundCard());
		mb.userPCI(new NetCard());
	}

}


 

三.  多态中(父类引用指向子类对象)成员的特点

1 非静态成员函数的特点:(因为存在覆盖)

1> 在编译时期:参阅引用型变量所属的类中是否有调用的方法。如果有,编译通过,如果没有,编译失败。

2> 在运行时期:参阅对象所属的类中是否有调用的方法。

(动态绑定:this所指对象去调用方法)

 简单总结就是:成员函数在多态调用时,编译看左边,运行看右边。

2. 成员变量的特点:无论编译和运行,都参考左边(引用型变量所属的类)。

3. 静态成员函数的特点:无论编译和运行,都参考做左边。

(静态绑定:静态方法一进内存就绑定在其所属类上了,所属于类)

原因:静态方法不需要对象,其决定于引用变量的所属类,所以一般不会覆盖静态方法。


四 Object Class

1> Object:是所有对象的直接后者间接父类,传说中的上帝。

该类中定义的肯定是所有对象都具备的功能。

2> Object类中已经提供了对对象是否相同的比较方法。

如果自定义类中也有比较相同的功能,没有必要重新定义。

只要沿袭父类中的功能,建立自己特有比较内容即可。这就是覆盖。

3> new A对象时会加载A.class文件,class文件中有文件名A,构造函数,和一些 方法,是这一类对象的共性,

所以用Class类来描述这一类对象(类文件对象)。


五 包

 

        对类文件进行分类管理,给类提供多层命名空间

        写在程序文件的第一行

        类名的全称是: 包名.类名

        包也是一种封装形式

 

1. 为了简化类名的书写,使用一个关键字:import.import 导入的是包中的类。

2. 建议,不要写通配符 ,需要用到包中的哪个类,就导入哪个类。

3. 建立定包名不要重复,可以使用url来完成定义,url是唯一的

4. 包访问权限总结:

1> 包与包之间进行访问,被访问的包中的类以及类中的成员,需要public修饰。

2> 不同包中的子类还可以直接访问父类中被protected权限修饰的成员。

3> 包与包之间可以使用的权限只有两种,public  protected

5. 包访问权限图示

 

作用域    当前类    同一package    子孙类     其他package

public          √                  √                     √                    √

protected   √                   √                     √                    ×

friendly       √                   √                     ×                    ×

private       √                    ×                     ×                    × 



---------------------- android培训------- android培训java培训、期待与您交流! ---------

posted @ 2012-07-19 17:44  积小流,成江海  阅读(273)  评论(0编辑  收藏  举报