黑马程序员――继承

----------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IO开发S</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------
3.8 继承

3.8.1继承的概述

1、继承:Java继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类。

2、继承的优点

     ①、提高了代码的复用性

     ②、让类与类之间产生了关系,有了这关系,才有了多态的特性

       注意:千万别因为要获取其他类的功能,简化代码而继承,必须是类与类之间有所属关系才可以继承。

3、父类,也称为基类,或超类

4、 聚集关系:关联的一种形式,代表两个类之间的整体 / 局部关系。聚集暗示着整体在概念上处于比局部更高的一个级别,而关联暗示两个类在概念上位于相同的级别。

       有两种特殊聚集:共享聚集和组合聚集。

l共享聚集:它的“部分”对象可以是多个任意“整体”对象的一部分

l组合聚集:整体拥有各部分,部分与整体共存。

3.8.2继承的特点

1、java语言:只支持单继承,不支持多继承,因为多继承容易带来安全隐患:当多个父类中定义相同功能,而功能的内容不同,子类不确定要运行哪一个但是java保留了这种机制,并以另一种体现形式来完成表示,多实现

2、java支持多层继承,也就是一个继承体系。如何使用一个继承体系中的功能?想要使用体系,先查阅体系父类的描述,因为父类定义了该体系的共性功能,通过了解共性功能,就可以知道该体系的基本功能。在具体调用时,要创建最子类对象,其原因是父类有可能创建不了对象,另外创建子类可以使用更多的功能。

3、子父类出现,类成员的特点:

    ⑴、变量:如果子父类中出现非私有的同名成员变量时,子类要访问本类中的变量时用this,子类要访问父类中的变量时用super。他们俩的用法几乎一致,只是俩代表的引用不同

    ⑵、函数:当子类出现和父类一模一样的函数时,子类对象调用该函数会运行子类函数的内容,如同父类的函数被覆盖了一样,也叫重写或覆盖。

    当子类继承了父类,沿袭了父类的功能,到子类中,但是子类虽具备该功能,但是功能的内容和父类不一致,这时,只需覆盖父类功能,保留父类的功能定义,并重写功能内容。

通过函数的复写可以提高扩展性

    覆盖注意事项:

     1)、子类的权限必须大于等于父类的权限,才可以覆盖。

     2)、静态只能覆盖静态

     3)、重载只看同名函数的参数列表,而重写的子父类方法必须一模一样

    ⑶、构造函数:

    子父类的构造函数是不可能一样的,因为构造函数的函数名与类名一致。在对子类对象进行初始化时,父类的构造函数也会运行。其原因是在子类构造函数默认的第一行有一条隐式的语句super(注意当第一行是this(),就没有super()),super会访问父类中空参数的构造函数。

    为什么子类一定要访问父类的构造函数?因为父类中的数据子类可以直接获取,所以子类对象在建立时,需要先查看父类是如何对这些数据进行初始化的的,所以子类在对象初始化时,要先访问父类的构造函数。如果要访问父类中指定构造函数,可以通过手动定义super语句来。

3.8.3 super关键字

   1、应用

   ⑴、在子类的构造方法内部引用父类的构造方法,如果要引用super的话,必须把super放在函数的首位。

class Base {
Base() {
System.out.println("Base");
}
}
public class Checket extends Base {
Checket() {
super();//调用父类的构造方法,一定要放在方法的首个语句
System.out.println("Checket");
}
public static void main(String argv[]) {
Checket c = new Checket();
}
}

   ⑵、在子类中调用父类中的成员方法或成员变量

class Country {
String name;
void value() {
name = "China";
}
}
class City extends Country {
String name;
void value() {
name = "Hufei";
super.value();//不调用此方法时,super.name返回的是父类的成员变量的值null
System.out.println(name);
System.out.println(super.name);
}
public static void main(String[] args) {
City c=new City();
c.value();
}
}

   ⑶、super直接传递参数

class Fu{
int num;
Fu(int num){
System.out.println("fu run"+"  "+num);
}
void show(){
System.out.println("fu show");
}
}
class Zi extends Fu{
Zi(){
//super();
super(4);// 传递参数
System.out.println("zi run");
}
void show(){
System.out.println("zi show");
}
}

  2、注意:

     ⑴、super语句必须放在子类构造函数的第一行

     ⑵、super和this都只能定义在第一行,所以只能定义一个。

     ⑶、通过super初始化父类内容时,子类的成员变量并未显示初始化,等super()父类完毕后,才进行成员变量显示初始化

3.8.4实例化过程

   1、子类的实例化过程:

    子类的所有的构造函数,默认都会访问父类中的空参数的构造函数。因为子类每一个构造函数的第一行都有一句隐式的super();当父类中没有空参数的构造函数时,子类必须手动通过super语句形式来指定要访问的父类中的构造函数。当然,子类的构造函数第一行也可以手动指定this语句来访问本类中的构造函数,子类中至少会有一个构造函数会访问父类中的构造函数

   2、对象实例化过程――以Person p = new Person();为例

lJvm会读取指定路径下的Person.class文件,并加载进内存,并会先加载Person的父类

l在堆内存中开辟空间,分配地址。

l在对象空间中,对对象中的属性进行默认初始化

l调用对应的构造函数进行初始化

l在构造函数中,第一行会先到调用父类中构造函数进行初始化

l父类初始化完毕后,再对子类的属性进行显示初始化

l在进行子类构造函数的特定初始化

l完毕后,将地址值赋给引用变量

3.8.6 final关键字

   1、final修饰的类不可以继承

   2、final修饰的方法不可以覆盖

   3、final修饰的变量是一个常量,只能赋值一次,且只固定显示化赋值

    4 、注意:类变量只有在final的修饰下,值才会固定,否则可以修改,static只能说明该值被共享,但不规定是固定的。

---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IOS开发</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------

详细请查看:<ahref="http://edu.csdn.net" target="blank">http://edu.csdn.net</a>

你可能感兴趣的:(黑马程序员――继承)