黑马程序员 6 Java面向对象编程 三

#1继承

A.子类,父类(基类)

B.继承的好处:

1、提高了代码的复用性。

2、让类与类之间产生了关系,为第三个条件——多态,提供了条件。

 

C. java中支持单继承,不直接支持多继承,但对C++中的多继承机制改良。

单继承:一个子类一个父类;

多继承;一个子类可以有多个父类。(java不支持,消除调用的不确定性)

 

D. java支持多层继承

 当要使用一个继承体系时:

1、查看该体系的顶层类,了解该体系的的基本功能。

2、创建体系中的最子类对象,完成功能的使用

 

*继承依赖关系,无关系不需要继承。相同部分可以抽取出来当做共同的父类成员。

E. 什么时候定义继承?

当类与类之间存在所属关系,就定义继承。

 

*子类中如果使用父类的成员,super.成员

*父类没有对象,成员存在于新建的子类对象中。

*子类可以继承父类中的私有变量但是不能直接访问,可以利用父类的方法访问。

 

F. 成员函数:

a.当子父类中出现一模一样的成员函数,则会运行子类的函数。这种现象叫做覆盖操作。这是函数在子父类中的特性。

b.函数的两个特性:

1.重载:同一个类中,overload

2.覆盖:子类中,覆盖也称为重写,覆写,override

c.覆盖注意事项:

1.子类覆盖父类方法时,子类权限必须大于等于父类的权限。

*父类中是private时,不算覆盖,因为父类方法子类不可用。

2.静态只能和静态相互覆盖。

d.什么时候覆盖:

当对一个类进行子类的扩展时,子类需要保留父类的功能声明,但是要定义子类中该功能的特有功能时,就是用覆盖操作完成。

*尽量少对源代码进行修改,带来安全隐患,不利于扩展。

 

实例分析:

子类成员VS父类成员:

class Animal{
    int leg = 4;//父类成员
  //父类方法
void showAnimal(){ System.out.println("Animal has "+leg+" legs."); } } class Bird extends Animal{
  //子类成员变量
int leg = 2;
  //子类方法
void showBird(){ System.out.println("Bird has "+leg+" legs,not "+super.leg+" legs."); } } public class Test7{ public static void main(String[] args){ Bird b = new Bird(); b.showAnimal(); b.showBird(); } }

 

*但是实际中极少定义子类变量与父类重名。

 

 

子类方法VS父类方法:

内存分析:

 

 

G.子父类中构造函数的特点:

a.构造系类对象时,父类的构造函数也运行了。因为子类构造函数第一行有一个默认的隐式空参数语句:super(),子类实例化过程中,子类所有构造函数都默认访问父类的空参构造函数;

*如果父类中没有空参数构造函数,子类也不能调用。

b. 为何要调用父类的构造函数:

  因为子类继承了父类,获取到了父类内容,所以在使用父类内容时,要先看父类是如何对自己的内容初始化的。

*super()必须在构造函数第一行,因为父类必须先构造。

*如果父类中没有定义空参构造函数,子类的构造函数必须super()明确调用。

*子类中的构造函数使用了this调用了本类构造函数时,那么super就没了,因为thissuper都要在第一行。但是super可以运行,因为别的构造函数中还有。

 

H. 一个对象实例化过程:

Person p = new Person();

1.JVM读取指定路径下的class文件加载进内存;并会先加载Person的父类(如果有);

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

3.并在对象空间中,对对象中的属性进行默认初始化。

4.调用对应的构造函数进行初始化。

5.在构造函数中,第一行会先调用父类中的构造函数进行初始化。

6.父类初始化完毕后,对子类的属性进行显式初始化。

7.再经行子类构造函数的特定初始化。

8.初始化完毕后,把地址赋给引用变量。

 

*继承——子父类中的构造函数——子类的实例化过程图解:

//father
class Animal{
    Animal(){
        super();
        show();
        System.out.println("Animal!");
    }
    void show(){
        System.out.println("Animal ~");
    }    
}
class Bird extends Animal{
    int leg = 4;
    Bird(){
        super();//通过super进行父类初始化时,leg并未显式初始化
        System.out.println("Bird!");
    }
    void show(){
        System.out.println("Bird has "+leg+" legs ~");
    }
}
public class Test8{
    public static void main(String[] args){
        Bird b = new Bird();
        b.show();
    }
}

在new对象之后已经赋给num默认值,在构造函数中调用父类构造函数,父类构造函数进栈,此时num还未被赋值。

黑马程序员 6 Java面向对象编程 三,古老的榕树,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。