继承、封装、多态

继承、封装、多态的理解

封装

将对象的属性和行为封装起来,其载体就是类,类通常对客户隐藏其实现细节,无须知道类内部是如何工作的,这就是封装。
避免了外部操作对内部数据的影响,提高了程序的可维护性。

继承

继承性主要利用特定对象之间的共有属性。如儿童是人,男士和女士也是人,他们具有共同特性,一对眼睛一个鼻子一个嘴巴,儿童可以复用人的属性和行为,同时添加了儿童自身独有的属性和行为。
在Java语言中将类似于儿童的类称为子类,将类似于人的类称为超类父类。子类只需要新增自己特有的方法,也可以把父类不适合的方法覆盖重写。
注意:子类的实例都是父类的实例,但不能说父类的实例是子类的实例。

多态

有了继承,才能有多态。
父类的对象变量可以引用本类的对象,也可以引用子类的对象。

由于Object类是超根类(祖先类),因此,它的对象变量可以引用所有类的对象。
特殊运算符: instanceof 属性

  • 注意:子类的对象变量可以引用父类的对象吗?
    答案: 不可以 若要进行,则必须强制转换。

即对象类型的转换分为以下两种:

       1) 向上转型: 子类的对象可以直接赋给父类的对象变量。 

这种现象也称之为类型的自动转换。

       2) 向下转型:  将父类的引用强制转换成子类的引用。 

注意: 它必须强制转换。

          格式:  (类型名) 对象变量;

当父类对象变量引用了子类的对象时,则问: 父类的对象变量是否可以直接调用子类的特有方法?

       答案: 否定的。

       例如: Animal 是父类,  Dog是子类,  而getName()方法是Dog子类特有的方法。

                因此,   当有 Anaimal  a = new Dog(); 时,

                则 a.getName(); 是否正确? 

                答: 错误。  

       问: 那如何访问?

       答: 需要先强制转换(向下转型)

          子类类名   对象变量 = (子类类名)父类的对象变量;

          即:   Dog d = (Dog)a;

          之后,  d.getName(); 此时,正确。

什么情况下需要将对象的引用实现强制转换(还原)(向下转型)?

  1. 一定是发生多态: 父类的对象变量引用了子类的对象。
    Object obj = new Student();
  2. 一定是想要去访问(调用)子类对象的特有属性或方法。
    父类的对象变量.子类对象的特有方法(属性); //则错了。
    Stringstr = obj.getSchool(); //错了。
    ((子类类名)父类的对象变量).子类对象的特有方法(属性); //则对了。
    Stringstr = ((Student)obj).getSchool(); //对了。

//多态: 父类的对象变量引用了子类的对象。

<span style="font-size:18px;"><span style="font-size:18px;">public class AnimalsTest {
	public static void main(String[] args) {
		Animal a = new Animal("动物");
		
		Dog d1 = new Dog("狗", "旺财", true, 2);
		Cat c1 = new Cat("猫", "豆豆", "blue");
		
		System.out.println( a );
		System.out.println( d1 );
		System.out.println( c1 );
		
		boolean flag = a instanceof Animal ; //判断a属于Animal类型吗
		System.out.println( flag );
		
		flag = a instanceof Dog;
		System.out.println( flag );
		
		flag = d1 instanceof Dog;
		System.out.println( flag );
		
		flag = d1 instanceof Animal;  //当结果为true时,说明它们之间存在继承关系。
		System.out.println( flag );
		
		//多态: 父类的对象变量引用了子类的对象。
		Animal a1 = new Dog("狗", "ABC", false, 3);
		//System.out.println( a1.getName() ); //调用a1的 getName()方法. 此时,它会去Animal类中找 getName()方法。若找不到,则报错。
	
		//判断a1是否拥有Dog类的特性,若有,则还原。
		if( a1 instanceof Dog ){
			Dog dd = (Dog)a1; //将a1强制转换为Dog类型。
			System.out.println( dd.getName() );
		}
		
		System.out.println("程序结束。");
	}
}
</span></span>

多态有编译时多态 和运行时多态。
第一个是通过方法重载实现;第二个是通过方法覆盖实现(子类覆盖父类方法)。

  1. 第一种就是我们调用方法是不用区分参数类型,程序会自动执行相应方法,如:
    加法运算,可以使int相加,可以是double相加,都是同一个方法名。
  2. 第二种就是动态绑定,使用父类引用指向子类对象,再调用某一父类中的方法时,不同子类会表现出不同结果。
    这样的作用就是扩展性极好,玩过网游的话应该知道
    游戏中有不同的角色,它们都有一个父类,它们做相同动作时表现出来的效果就会不一样,比如跑,魔法师的跑跟战士的跑就不会一样,这就是俩者都覆盖了父类中的跑方法,各自有自己的现实,表现出来多态。
    如果有一天你想再加个角色,只用再写一个类继承该父类,覆盖其中的跑方法就行了,其他代码不用怎么改,所以可维护性也很好。

比如 你没用多态的话 ,你没实例化一个对象 就要new一下,那假如你那天改变了需求了呢?那是不是又要改里面的?这样不好,所以 你可以通过多态,把需要相似的给提出来,然后继承它,以后需要扩展你仅仅只是继承而已。

这个需要多看代码 才可以更深刻理解。假设有一个类 叫 鸟类,它拥有属性翅膀,拥有方法鸣叫,如下

public class Bird{
	private Wing wing;
	public void moo(){
		System.out.println("鸟叫声");
	}
}

鸟类封装了 翅膀类和moo方法;另外有两个类都继承鸟类并重写了moo方法,分别是鹦鹉和麻雀如下:

//鹦鹉类
public class Parrot extends Bird{
	public void moo(){
		System.out.println("鹦鹉的叫声");
	}
}
//麻雀类
public class Sparrow extends Bird{
	public void moo(){
		System.out.println("麻雀的叫声");
	}
}

方法重写应该懂吧,不懂自己找书看吧;然后你有个妻子她想听鸟叫,就有个妻子类

public class Wife{
	public void listen(Bird bird){
		bird.moo();
	}
}

这时多态就很好的体现了,你妻子想听鸟叫,无论什么鸟都可以给她,但是你想让她和鹦鹉说话,你就买了一只鹦鹉传给listen方法,结果你妻子听到了鹦鹉的叫声,程序输出:鹦鹉的叫声

public static void main(String[] args) {
	new Wife().listen(new Parrot());
}

多态实现了动态绑定,让程序有了很好的扩展性,比如你以后想买一只燕子送给你妻子,就只需要写个燕子类Swallow继承Bird方法就可以了,而不需要再在妻子类里添加一个方法listen(Swallow swallow)。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值