JAVA三大特性之 多态特性详解

 * 多态:    父类的 引用变量 指向了子类的对象
             或者
 *         接口的 引用变量 指向了接口实现类对象

 * 多态前提:必须存在 继承或者 实现关系
 * 多态要注意的细节:
 *     1.多态情况下,子父类 存在 同名的成员变量(包括 非静态和 静态),默认 访问父类的成员变量
 *     2.多态情况下,子父类 存在 同名的非静态函数时,默认的是 子类的成员函数
 *     3.多态情况下,子父类 存在 同名的静态函数时,默认访问的父类的成员函数
 *     4.多态情况下,不能访问 子类 特有的成员 
 *     总结: 对于 同名 子父类的成员,只有 非静态的成员方法,访问的是 子类 ,其他的访问的都是父类 

/*
 * 	需求:定义一个图形,矩形,圆形 三个雷,所有的图形都具备计算 面积和周长的方法
 * 	
 * 	要求:
 * 		1.定义一个方法 可以接受 任意类型的图形对象,
 * 		在该方法内部 调用 图形的周长和面积的方法
 * 
 * 		2.定义一个方法 ,可以返回 任意类型的图形对象
 *  
 * */

abstract class Shape{
	
	public abstract double getArea();
	public abstract double getLength();
}

//单继承:   java是单继承的,一个类 最多 只能有一个 直接父类
//(一种事物 只能够 是属于 唯一的另一种事物)
class Rect extends Shape{
	
	double width;
	double height;
	
	

	public Rect(double width, double height) {
		this.width = width;
		this.height = height;
	}

	@Override
	public double getArea() {
		
		return width*height;
	}

	@Override
	public double getLength() {
	
		return 2*(width+height);
	}
	
}

class Circle extends Shape{
	
	public static final double PI = 3.14;
	double r;
	
	

	public Circle(double r) {
		super();
		this.r = r;
	}

	@Override
	public double getArea() {
		// TODO Auto-generated method stub
		return PI*r*r;
	}

	@Override
	public double getLength() {
		// TODO Auto-generated method stub
		return 2*PI*r;
	}
	
}


public class Demo1 {
	
	public static void main(String[] args) {
		
		Rect r = new Rect(2.0, 3.0);
		Circle c = new Circle(3.0);
		
		//定义一个方法 print。具备多种重载方式,打印传进去的各种图形的周长和面积
		//print(r);
		//print(c);
		
		
		//但是 ,我们希望在一个方法中 实现 (使用多态)
		Shape s1 = new Rect(3.0, 4.0);
		Shape s2 = new Circle(4.0);
		
		
		print(s1);
		print(s2);
		
		//Shape s3 = getShape(1);
		//Shape s4 = getShape(-1);
		
		//强制类型转换
		Rect r2 = (Rect)getShape(1);
		
		Circle c2 = (Circle)getShape(-1);
		
		
	}
	
	//多态的用法:
	//父类类型 可以 作为 方法的返回值,具体返回的类型可以是 任意 子类类型
	//定义一个方法,可以返回任意类型的图形对象
	public static Shape getShape(int i){
		//通过i的 值来返回
		if(i>0){
			return new Rect(4.0, 5.0);
		}else{
			return new Circle(4.0);
		}
		
	}
	
	
	
	//多态的作用: 
	//父类可以作为方法的参数类型,具体 传进方法的参数 可以是 任意 子类类型
	//定义一个方法,可以接受 任意类型的图形对象
	private static void print(Shape s) {
		
		/*	
		 	传进去的 s 是一个 父类的显式类型(编译时类型),
			如何知道 到底是 什么 实际类型(运行时类型)?
		*/
		String shapeName = "";
		if(s instanceof Rect){
			shapeName = "矩形";
		}else if(s instanceof Circle){
			shapeName = "圆形";
		}
		
		System.out.println(shapeName+"的面积:"+s.getArea());
		System.out.println(shapeName+"的周长:"+s.getLength());
		
	}
	
	/*
	private static void print(Circle c) {
		
		System.out.println("圆形的周长为:"+c.getLength());
		System.out.println("圆形的面积为:"+c.getArea());
		
	}

	private static void print(Rect r) {
		System.out.println("矩形的周长为"+r.getLength());
		System.out.println("矩形的面积为"+r.getArea());
		
	}*/

}

 


     多态情况下,不能访问子类特有的成员
  多态 情况下,如果需要 调用到子类 特有的成员,那么需要进行 强制类型转换

 *         基本数据类型:
 *         小数据类型->大数据类型:  自动类型转换
 *         大数据类型->小数据类型:  强制类型转换
 *         引用数据类型转换
 *         子类数据类型->父类数据类型: 自动类型转换
 *         父类数据类型->子类数据类型: 强制类型转换
 *         ClassCastException:强制类型转换异常

 *         在转换之前 一般 使用 instanceof关键字 先判断


class A{
	int a = 10;
}

class B extends A{
	int b = 20;
}

class C extends A{
	
}

public class Demo2 {

	public static void main(String[] args) {
		A a = new B();  //自动类型转换
		//将 父类 的 类型 转换为 子类的类型(大转小:强转)
		B b = (B) a;	//强制类型转换
		
		//C c = (C) a;  //ClassCastException
		System.out.println("a属于 B类型:"+(a instanceof B));
		System.out.println("a属于 C类型:"+(a instanceof C));
		
		System.out.println(b.b);
	}
}

实现关系下的多态:接口的引用 类型变量 指向了 接口实现类的对象
     *     接口中的方法 全部 是 非静态。多态情况下, 子父类 存在同名的非静态函数时,
     *     默认是访问子类的非静态函数


interface Dao{
	
	/*
	 * 	接口中的方法 全部 是 非静态。多态情况下, 子父类 存在同名的非静态函数时,
	 * 	默认是访问子类的非静态函数
	 * 
	 * */
	 
	void add(String user);
}
class UserDao implements Dao{

	@Override
	public void add(String user) {
		// TODO Auto-generated method stub
		System.out.println("添加用户"+user+"成功");
	}
	
}

public class Demo3 {

	public static void main(String[] args) {
		Dao d = new UserDao(); //实现关系下的多态
		d.add("张三");
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值