1、属性继承
2、成员方法继承 涉及方法覆写
3、构造方法继承 super关键字this关键字应用
类加载全过程分析
package cn.china; public class TestDemoJ { public static void main(String[] args) { // student s=new student(); // s.name="张三"; // s.age=22; // s.study(); // TODO Auto-generated method stub Son son=new Son(); son.show(); son.show();
} } /** * 继承的好处: * 1.提高了代码的复用性 * 2.让类与类之间产生关系,给第三个特征多态提供了前提 * * java中支持单继承,不支持多继承,但对C++中的多继承机制进行改良 * 单继承:一个子类只能有一个直接父类。 * 多继承:一个子类可以有多个直接父类。(java中不支持,但是有改良)主要原因是;多个父类中有相同成员,会产生调用的不确定性 * 在java中是通过“多实现”的方式体现的*/ //class A{ // void show(){ // System.out.println("a"); // } //} //class B extends A,C{} //class C { // void show(){ // System.out.println("a"); // } //} /** * java支持多层继承。 * C继承B B继承A * 就会出现继承体系 * 需要使用一个继承体系时 * 1、查看该体系中的顶层类 * 2、创建体系中的最子类对象,完成功能使用 * * class DemoA{ * void show1(){} * void show2(){} * } * class DemoB extends DemoA{ *void show1(){} * void show3(){} * } * 什么时候定义继承呢? * 当类与类之间存在着所属关系的时候,就定义继承。XX是YY中的一种,那么XX extends YY*/ class Person1{ String name; int age; } class student extends Person1{ void study(){ System.out.println(name+"....student study...."+age); } } class Worker extends Person1{ void work(){ System.out.println("worker...work"); } } /** * 在子父类中,成员的特点体现。 * 1.成员变量 * 2.成员函数 * 3.构造函数 * * 当本类的成员和局部变量重名用this区分 * 当子类父类成员变量同名用super区分父类 * this和super用法相似 * this:代表一个本类对象的引用, * super并不代表父类对象,可以认为代表一个父类的空间。*/ class Fu{ int num=4; } class Zi extends Fu{ int num=5; void show(){ System.out.println(this.num+"...."+super.num); } } /** * 成员函数 * 当子父类中出现成员函数一模一样的情况会运行子类的函数,这种现象,称为覆盖操作,这是函数在子父类中的特性 * 函数两个特性 * 1、重载,是在同一个类中 overload * 2、覆盖,子类中,覆盖也成为重写override * 覆盖注意事项 * 1、子类方法覆盖父类方法时,子类权限必须要大于等于父类的权限。 * 2、静态只能覆盖静态,或被静态覆盖 * 什么时候使用覆盖操作? * 当对一个类进行子类的扩展时,子类需要保留父类的功能声明, * 但是要定义子类中该功能的特有内容时,就使用覆盖操作完成*/ class Father{ void show(){ System.out.println("f"); } } class Son extends Father{ void show(){ System.out.println("s"); } } /** * 子父类中的构造函数的特点 * 在子类构造对象时,发现,访问子类构造函数时,父类也运行了。 * 为什么呢? * 原因是:在子类的构造函数中第一行有一个默认的隐士语句super(); 调用的就是父类的空参数构造函数 * 子类的实例化过程,子类中所有的构造函数默认都会访问父类中的空参数的构造函数 * 为什么子类实例化的时候要访问父类中的构造方法? * 那是因为子类继承了父类,获取到了父类中的内容(属性),所以在使用父类内容之前,要先看父类是如何对自己的内容进行初始化的。 * 所以子类在构造对象时,就必须访问父类中的构造函数。 * 那么如何完成这个必须动作,就在子类的构造函数中加入了super();语句。 * * 如果父类中没有定义空参构造函数,那么子类的构造函数必须用super明确要调用父类中哪个构造函数; * 同时子类构造函数中如果使用了this调用了本类构造函数,那么super就没有了,因为this和super都只能定义在第一行,所以只能有一个,但是要保证的是,子类中this调用的构造函数中调用了父类的super; * 注意:super语句必须要定义在子类构造函数的第一行,因为父类的初始化动作要先完成。*/ class Fu1{ int num; Fu1(){ num =10; System.out.println(" A fu run!"); } Fu1(int x){ System.out.println(" B fu run!"+x); } } class Zi1 extends Fu1{ int num; Zi1(){ //super(); System.out.println(" C Zi run!"+num); } Zi1(int x){ this(); //super(); //super(x); System.out.println(" D zi run!"+x); } } /** * 一个对象的实例化过程 * Person P=new Person(); * 1、JVM会读取指定路径下的Person.class文件,并加载进内存, * 并会先加载Person的父类(如果有直接父类的情况下), * 2、在堆内存中的开辟空间,分配地址。 * 3、并在对象空间中,对对象中属性进行默认初始化。 * 4、调用对象的构造函数进行初始化 * 5、在构造函数中,第一行会先调用父类中构造函数进行初始化。 * 6、父类初始化完毕后,在对子类的属性进行显示初始化。 * 7、再进行子类构造函数的特定初始化 * 8、初始化完毕后,将地址值赋值给引用变量*/
package cn.java; class Fu{ void show(){ System.out.println("Fu....run"); } Fu(){ show(); } } class Zi extends Fu{ int num=8; void show(){ System.out.println("Zi...run"+num); } Zi(){} } public class JavaExtends1 { public static void main(String[] args) { Zi zi=new Zi(); zi.show(); // TODO Auto-generated method stub } }