黑马程序员:面向对象之-----继承

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

继承
 特点:就是将类与类之间,共性的属性和行为,进行独立进行封装
    让类与类之间产生关系
  好处:
  提高了代码的复用性。
	因为关系给多态这个特征提供了前提
 多个类中存在相同属性和行为时,可以将这些内容抽取到单独一个类中,
 那么多个类无需再定义这些属性和行为,只要继承那个类即可

 多个类可以称为子类,单独这个类称为父类 超类、基类
 子类可以直接访问父类中的非私有的属性和行为

  在JAVA中继承的体现
  1、 java中只支持单继承。不直接支持多继承,保留了多继承机制,用另一种来体现
  2、java还支持多层继承(b继承a ,c继承b, d继承c);
  父类是通过不断的向上抽取共性内容而来的。
继承体系
     想要使用一个体系:就查看该体系中顶层类中的内容,
     因为该 类中定义了该体系的最基础最共性功能
     当使用该体系时,创建对象最好以最子类为主
简单说:
     使用一个体系
      查阅父类内容,创建子类对象
什么时候定义继承??
 当类与类之间存在着所属关系(is a )时,就可以使用继承
其实就是什么是什么(XXX是YYY)中的一种,就可以称为继承 xxx extends yyy

父类中的功能是不是你都该具备的吗??
实在分不清楚,那就判断如果真的继承了,父类中的内容子类是否真可以具备
如果有不可以或者不需要具备的,那么就不要继承

例如:
  class a{}
  class b extends a{}  //单继承  java 只支持单继承
 class c extends a,b  //多继承 但是JAVA 里面不支持

为什么不支持多继承??
例如:
  class a
  {
   void show()
   {
   System.out.println("a");
   }
  }
  class b
  {
  void show()
   {
   System.out.println("b");
   }
  }
  class c extends b,a
  {
    new c().show();  //就会产生不确定性
  
  }
   当c继承a、b时,c 来调用父类的方法时,无法确定是调那个父类的方法。
一个孩子只能有一个父亲,但是一父亲能有多个孩子

--------------------------
子父类的成员的特点

1、成员变量
2、成员函数
3、构造函数

对于同名成员变量的
 super和 this的用法很相像
 不同之处在于
  this:代表的是一个对象
  super:代表的是父类所属的空间

注意:一般情况下,不会出现该种同名情况

class Fu
{
  int num=3;  //成员的变量
}
class zi extends Fu
{
 int num2=4;
 public void show()
 {
  int num=5;  
 System.out.println(this.num);  //如果想打印4 就是要在变量前面加标示 this.num
  System.out.println(super.num);//如果想打印父类的3 就是要在变量前面加标示 super.num
 }

}
class Extends Demo2
{
public static void main()
{
  Zi z=new Zi();
   z.show();
}

}
当子父类中出现了同名的成员变量时,如果在子类中使用父类中的变量
需要通过super关键字来区分
如果子类的方法里面有变量时,就会使用方法里面的变量,这就是java的就近原则
当子类里面也有变量的时候 ,java就会直接显示子类里面的变量
如果方法里面还有变量,那就会显示方法里面的那个变量的值 


----------------------------------------------------
子父类中的成员函数
 当子父类中出现了一模一样的方法
 这种情况,我们称之为:函数的一个在子父类中特性:覆盖(override) 重写 
class Fu
{
  public void show()
 {
  System.out.println(“FU SHOW”);
 }
}
class zi extends Fu  
{
 public void show()  
 {
  super.show();
  System.out.println("ZI SHOW");
 }

}
class Extends Demo2
{
public static void main()
{
  Zi z=new Zi();
   z.show();
}

}
当子类运行 z.show()时,如果子类中有这个方法,子类就会先调用自己的方法,
如果没有就会通过super()来调用父类的方法。



 覆盖的应用:
   对于后期功能的扩展,不建议对原有代码进行修改

   学习了继承,可以通过对已有类进行子类的扩展来完成功能的定义 
   如果是对原有的类已有功能进行改写
   只需要保留原有类的功能声明。重新定义 功能的主体内容,即可
   这是是覆盖的应用

   如果子父类都有相同的方法,但是在保证父类的功能方法不变的情况下,那就可以通过覆盖来完成
   将父类原有的功能保留,在子类中重新定义功能,在调用父类的方法。super.show();
调用父类的方法。

  例如: 移动手机



  覆盖的注意事项:
1、必须要保证返回值 类型 函数名 参数列表要一模一样
2、子类覆盖父类时,必须要保证权限大于等于父类 
3、覆盖中,如果有一方是静态,那么另一方必须是静态

 只要在调用中出现不确定情,java 就会报错啊
  所以在程度中不能出现。


-------------------------------------------------
子父类的构造函数

  通过结果发现,父类中的构造函数先运行,然后才运行子类的构造函数内容
为什么了?
 因为在子类的构造函数的第一行默认都有一条隐式的 super();
 在默认调用父类中的空参数构造函数

为什么子类的构造函数必须要访问父类中的构造函数?

  子类继承了父类,可以使用父类中的数据,在使用前,应该先看一下父类是如何对该数据进行初始化的
  所以子类的构造函数都必须在初始化前先执行父类的构造函数
  这也是子类的实例化过程


class Fu
{
 Fu()
 {
 System.out.println("fu run");
 }
}
class zi extends Fu  
{
 Zi()
 {

 //super();  默认的父类的空参数构造函数
  System.out.println("zi run");
 }
 }

}
class Extends Demo2
{
public static void main()
{
  Zi z=new Zi();
   z.show();
}

}
子类的构造函数默认都访问父类中的空参数构造函数
如果父类中没有空参数构造函数,或者子类要访问父类中指定的构造函数
那么必须在子类中用显示的super语句明确要访问哪个父类的构造函数

super语句中必须要定义在子类构造函数的第一行?
	因为父类初始化动作要先执行。

this  语句 和super语句 可以同时存在吗?
	不可以
 为什么this(),super()必须定义在构造函数的第一行
	因为初始化值要先执行

*****类加了什么权限,那方法里面的默认权限就是和类相同

应用
 class Person
 {
 private String name;
 private int age;
 Person(String nam,int age)
 {
 this.name=name;
 this.age=age;
 }

 }
 class Student extends Person
 {
  Student(String name,int age)
  {

  //this.name=name; 
  //this.age=age;   
   super(name,age); 

   }

   public void study()
   {
   }
 
 }
 因为父类的属性是私有了。在就是父类已经把这些事情已经做完了。
我们只要调用就可以了。但是这个函数是构造函数
直接通过父类的super()进行参数的传递


就是父类把事情做了。子类就只要直接去调用它就可以了
-----------------------------------------
覆盖只发生子父类的函数上

继承的弊端:打破了封闭性

final(最终)关键字
	final可以修饰类,可以修饰方法,可以修饰变量
	final修饰的类不可以被继承
	final修饰的方法不可以被覆盖
	final修饰的变量是一个常量,只能被显示赋值一次
其实就 是为了给固定的常量起个名字,并用final修饰后,该名称的值就固定了
这是为了增加程序的阅读性,只要是被final修饰的常量,
名称有规范。所有字母都 大写,如果由多个单词组成的, 用_分隔

只要有固定的数据出现,就用定义名称将其记录,并用final修饰

例如:
final class Fu   //被final修饰的类不可以被继承
{
	final int num;  //因为有默认值,所以会报错。
	 被final修饰的必须要显示初始化值 且只能进行一次赋值

	 
   final void show() //final修饰方法
  {
  }
}
class Zi extends Fu
{
  void show()
  {
     final int nun=4;  //被final修饰的变量只能进行一次显示赋值
  }

}

public static int num=9; 全局变量
加final后就叫全局变量


----------------------------------------------
抽象类

例如:
   犬科(狼、狗)
abstract class 犬科
{
 abstract 吼叫();
}

class 狼 extends 犬科
{
 void 吼叫()
 {
 System.out.println("嗷嗷");
 
 }
}
class 狗 extends 犬科
{
 void 吼叫()
 {
 System.out.println("汪汪");
 }

 
 抽象类的概述
	其实就是具体的事物不断地向上抽取而来的
	而且只抽取了方法的声明,而没有抽取方法的实现
	所以该方法是抽象方法,而抽象方法必须存储在抽象类中


抽象类:其实就是对事物的描述,定义了事物的具体的基本的功能,但是有些功能不确定具体的内容
	这个内容有其子类完成的具体的内容的定义

抽象类的特点:
	1、没有方法主体的方法是抽象方法,必须定义在抽象类中
	  抽象方法和抽象类必须用abstract关键字修饰
	2、抽象类不可以被实例化,也就是说,不可以用new创建对象。因为调用抽象方法没有意义 
	3、抽象类必须由自己的子类覆盖了所有的抽象方法后,其子类才可以被实例化,否则,该子类还是一个抽象类


抽象类的细节
 1、抽象类中是否有构造函数
	有的,抽象类的构造函是给子类进行初始化的
	抽象类和非抽象类异同点:
	相同: 
	抽象类和非抽象类都是用于描述事物
	都可以定义类中应该有的成员。成员变量、成员函数、构造函数
	不同:
	抽象类可以定义抽象方法,非抽象类不行
	抽象类不可以实例化,而非抽象类可以实例化


  2、抽象类中可不可以不定义抽象方法?
	可以的。如果抽象类中没有定义 抽象方法,那么目的是一个,就是不让该类创建对象
	这种情况有,在awt中的适配器类就是如此,但是不多

  3、抽象关键字不可以和哪些关键字共存?
	private :如果加了private 那就是子类不知道 你有这个方法了。
	static : 如果加static 静态了  就可以用类名.方法名进行调用了。所以用抽象就没有意义 了

	final;  会出现提示显示无非法的组合

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值