java继承的概述

1 继承的概述先观察如下代码

package java007;/** * 2017/9/9 * 说明:学生 */public class Student {    String name;    int age;    public void study(){        System.out.print("我叫"+name+",今年"+age+",我是一名学生,正在学习");    }}
package java007;/** * 2017/9/9 * 说明:工人 */public class Worker {    String name;    int age;    public void work(){        System.out.print("我叫"+name+",今年"+age+",我是一名工人,正在工作");    }}
package java007;/** * 2017/9/9 * 说明: */public class StudentAndWorkderTest {    public static void main(String[] args) {        Student s = new Student();        s.name = "张三";        s.age = 15;        s.study();        Worker w = new Worker();        w.name = "李四";        w.age = 34;        w.work();    }}

我们可以发现学生类和工人类中都有姓名和年龄属性,属于重复字段,那么如何解决?,且看如下代码。  

package java007;/** * 2017/9/9 * 说明: */public class Person {    String name;    int age;}
package java007;/** * 2017/9/9 * 说明:学生 */public class Student extends Person {    public void study(){        System.out.print("我叫"+name+",今年"+age+",我是一名学生,正在学习");    }}
package java007;/** * 2017/9/9 * 说明:工人 */public class Worker extends Person{    public void work(){        System.out.print("我叫"+name+",今年"+age+",我是一名工人,正在工作");    }}
package java007;/** * 2017/9/9 * 说明: */public class StudentAndWorkderTest {    public static void main(String[] args) {        Student s = new Student();        s.name = "张三";        s.age = 15;        s.study();        Worker w = new Worker();        w.name = "李四";        w.age = 34;        w.work();    }}

继承的好处:①提高了代码的复用性。②让类与类之间产生关系,给第三个特征多态提供了前提。  

2 继承的特点Java中支持单继承(一个子类只能有一个父类),不直接直接多继承,支持多层继承。

3 super关键字当本类的成员变量和局部变量同名的时候,使用this区分。当子父类的成员变量同名的时候,使用super区分父类。this和super的用法很相似。

示例1:本类的成员变量和局部变量同名的时候

package java007;/** * 2017/9/9 * 说明: */class Fu{    private int age = 20;    public void show(){        int age = 10;        System.out.print("局部变量:"+age+",成员变量:"+this.age);    }}public class ExtendsDemo {    public static void main(String[] args) {        Fu f = new Fu();        f.show();    }}

解释说明:①先使用javac ExtendsDemo.java命令将ExtendsDemo编译成class文件,当然,顺便将Fu.java也编译成class文件。②使用java ExtendsDemo命令,虚拟机会从方法区中,将main()方法识别,并加载到栈中。③执行了new Fu();会在堆内存中开辟一个空间,(将Fu(){}加载到栈内存中,因为这一部分对本程序而言不是很重要,所以省略相关描述),用来存储对象,并初始化age=0。然后执行到private int age = 20;的时候,就将20赋值给age,此时age在堆内存中是20。④Fu f = new Fu();main()方法所在的栈内存中,开辟了一个引用变量f,然后将堆内存中的对象的地址赋值给f,那么此时f就指向堆内存中的对象。⑤f.show();从方法区将show()方法加载到栈中,此时,注意的是,show()方法内部就包含了this关键字,同时f变量的地址值给了this,因为this表示的是当前对象的引用,而调用show()方法的恰恰是f,所有this和f此时的值是相同的,那么show()方法也指向了堆内存中的对象,然后在show()方法内部开辟了一个age变量,这个age变量是栈内存中show()方法内部的局部变量,而想获取堆内存中的age变量,只能通过show()方法内存的this关键字了。  

示例2:子类和父类的成员变量不同的时候

package java007;/** * 2017/9/9 * 说明: */class Fu{     int age1 = 20;}class Zi extends Fu{    int age2 = 30;    public void show(){        System.out.print(age1+" "+age2);    }}public class ExtendsDemo {    public static void main(String[] args) {        Zi z = new Zi();        z.show();    }}

解释说明:通过上面的程序貌似可以这样解释,第一,变量名是不一样的,第二,子类是继承了父类,而子类中没有age1成员变量,所以从父类中继承(拷贝)了age1成员变量。  

示例3:子父类的成员变量相同的时候

package java007;/** * 2017/9/9 * 说明: */class Fu{     int age = 20;}class Zi extends Fu{    int age = 30;    public void show(){        System.out.print(age);    }}public class ExtendsDemo {    public static void main(String[] args) {        Zi z = new Zi();        z.show();    }}
package java007;/** * 2017/9/9 * 说明: */class Fu{     int age = 20;}class Zi extends Fu{    int age = 30;    public void show(){        System.out.print(age+" "+super.age);    }}public class ExtendsDemo {    public static void main(String[] args) {        Zi z = new Zi();        z.show();    }}

解释说明:通过上面的程序貌似可以这样解释,子类和父类成员变量相同的时候,子类可以将父类相同成员变量覆盖,其实不然,且看下面分解。  

4 函数覆盖(重写)示例:子父类中的方法名不同

package java007;/** * 2017/9/10 * 说明: */class Fu{    public void show1(){        System.out.print("Fu的show1方法");    }}class Zi extends Fu{    public void show2(){        System.out.print("Zi的show2方法");    }}public class ExtendsDemo2 {    public static void main(String[] args) {        Zi z = new Zi();        z.show1();        z.show2();    }}

示例:子父类中的方法名同名

package java007;/** * 2017/9/10 * 说明: */class Fu{    public void show(){        System.out.print("Fu的show方法");    }}class Zi extends Fu{    public void show(){        System.out.print("Zi的show方法");    }}public class ExtendsDemo2 {    public static void main(String[] args) {        Zi z = new Zi();       z.show();    }}

当子类中出现成员函数和父类的一样的时候,会运行子类的成员函数,从表现上看。好像是子类的成员函数“覆盖”了父类的成员函数,这种现象,被称为重写或者覆盖。函数的两个特性:重载。同一个类中。覆盖。子类中,也称为重写。    重写的注意事项:子类方法覆盖父类方法时,子类方法的权限必须>=父类方法的权限。

5 子类的实例化过程示例:

package java007;/** * 2017/9/10 * 说明: */class Fu{   public Fu(){       System.out.println("Fu的构造方法");   }}class Zi extends Fu{    public Zi(){        System.out.println("Zi的构造方法");    }}public class ExtendsDemo2 {    public static void main(String[] args) {        Zi z = new Zi();    }}

在子类构造对象的时候,发现,访问子类构造函数的时候,父类也运行了。这是为什么?因为,在子类构造方法中的第一行有一个默认的隐式语句:super();j如下代码所示。 

package java007;/** * 2017/9/10 * 说明: */class Fu{   public Fu(){       System.out.println("Fu的构造方法");   }}class Zi extends Fu{    public Zi(){        super();//调用的是父类的默认的空参数构造函数        System.out.println("Zi的构造方法");    }}public class ExtendsDemo2 {    public static void main(String[] args) {        Zi z = new Zi();    }}

示例:

package java007;/** * 2017/9/10 * 说明: */class Fu{    public Fu(){        show();    }    public void show(){        System.out.print("fu show");    }}class Zi extends Fu{   int num = 8;   public Zi(){   }   public void show(){       System.out.print("zi show:"+num);   }}public class ExtendsDemo2 {    public static void main(String[] args) {        Zi z = new Zi();        z.show();    }}

解释:先将父类进行初始化,再将子类进行初始化。  

6 final关键字final可以修饰类、方法和变量。final修饰的类不可以被继承。final修饰的方法不可以被重写。final修饰的变量是一个常量,只能被赋值一次。内部类只能访问被final修饰的局部变量。

示例:final修饰变量,变为常量

class Person{    private final int age = 10;}

示例:final修饰变量,变为常量

class Person{    private final int age ;    {        age = 20;    }}

示例:final修饰变量,变为常量

class Person{    private final int age ;    public Person(int age){        this.age = age;    }}

最糟糕的行为是抱怨,最易见效 的努力是从自己做起。

java继承的概述

相关文章:

你感兴趣的文章:

标签云: