继承、重载、重写和子类实例化

来源:互联网 发布:难言之欲网络剧资源 编辑:程序博客网 时间:2024/06/06 09:37

1、继承

(1)当多个类中存在相同的属性和行为时,将这些内容抽取到单独的一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。
(2)多个类称为子类,被继承的单独的类称为父类或超类。
(3)子类可以直接访问父类中的非私有属性行为
(4)通过extends 关键字使类和类之间产生继承关系。
见示例:
//继承、instanceof的用法、对象类型的强制类型转换public class ExtendsDemo {    public static void main(String[] args){        Student s = new Student("张三",23);        Teacher t = new Teacher("李四",35);        Print(s);        Print(t);    }    private static void Print(Person p){        if(p instanceof Student){        //instanceof 关键字用来判断一个实例是否是某一类型,是返回true,否返回false。            Student s = (Student) p;     //这里必须使用类型转换,Person()类中没有 learn()方法,强制转型为 Student类型,才能调用learn()            System.out.print(s.name+" "+s.age+" "+s.eat()+" ");            s.learn();        }        else if(p instanceof Teacher){            Teacher t = (Teacher) p;            System.out.print(t.name+" "+t.age+" "+t.eat()+" ");            t.teach();        }        else{ System.out.println("error");}    }}class Person{    public String name;    public int age;    public String eat(){        return "吃饭";    }}class Student extends Person{        //extends 关键字表示继承关系    Student(String name,int age){        this.name = name;        this.age = age;    }    public void learn(){        System.out.println("学习");    }}class Teacher extends Person{    Teacher(String name,int age){        this.name = name;        this.age = age;    }    public void teach(){        System.out.println("教课");    }}
学生跟老师都有姓名和年龄这两个属性,都有吃东西这个行为。
所以把这两个属性和一个行为抽取出来,封装到一个单独的 Person() 类中。
Student() 类和 Teacher() 类再使用 extends 关键字继承 Person() 类的成员变量和成员函数。
主函数的 Print()方法中,因为传递的参数是 Person 父类,当用instanceof 关键字判断实例是否是 Student类型后,要用强制类型转换,从 Person类型强制转换为 Student类型,才能调用 Student类型的 Learn()方法。

Java只支持单继承,就是一个子类只能有一个父类,不支持多继承,但在类与接口间支持多实现

2、重载

重载函数是函数的一种特殊情况,为方便使用,允许在同一范围中声明几个功能类似的同名函数,但是这些同名函数的形式参数(指参数的个数、类型或者顺序)必须不同,也就是说用同一个运算符完成不同的运算功能。这就是重载函数。重载函数常用来实现功能类似而所处理的数据类型不同的问题。
两个重载函数必须在下列一个或两个方面有所区别:(只看参数)
1.、函数有不同参数。
2、函数有不同参数类型,


3、函数覆盖/重写(OverRide)

(1)子类中出现与父类一模一样的方法时,会出现覆盖操作,也称为重写或者复写。
(2)父类中的私有方法不可以被覆盖。
(3)在子类覆盖方法中,继续使用被覆盖的方法可以通过super.函数名获取。

覆盖注意事项:
(1)覆盖时,子类方法权限一定要大于等于父类方法权限
(2)静态只能覆盖静态
覆盖的应用:当子类需要父类的功能,而功能主体子类有自己特有内容时,可以复写父类中的方法,这样,即沿袭了父类的功能,又定义了子类特有的内容。
//输出结果为“吃苹果 吃西瓜”public class OverRideDemo{    public static void main(String[] args){        Student s = new Student();        s.eat();        s.eat_2();    }}class Person{    public void eat(){        System.out.println("吃西瓜");    }}class Student extends Person{    public void eat(){        System.out.println("吃苹果");    }    public void eat_2(){        super.eat();  //使用 super.函数名() 来调用父类的函数    }}

4、子类的实例化过程

对象的初始化:
(1)
静态代码块随着类的加载最先初始化。
(2)默认初始化。
(3)构造代码块初始化。
(4)构造函数初始化。
Person p = new Person();/**因为new用到了Person.class 所以会先找到Person.class 文件并加载到内存中。执行该类中的static代码块,如果有的话,给Person.class 类进行初始化。在堆内存中开辟空间,分配内存地址。在堆内存中建立对象的特有属性,并进行默认初始化。对属性进行显示初始化。对对象进行构造代码块初始化。对对象进行对应的构造函数初始化。将内存地址赋给栈内存中的p 变量。*/

子类的实例化:
(1)子类的实例创建时,会先默认访问父类中空参的构造函数,因为子类初始化要首先初始化父类。
(2)子类中,每一个构造函数的第一行都有一条默认的语句 super(); 
(3)子类会具备父类中的数据,所以要先明确父类是如何对这些数据初始化的。
(4)当父类中没有空参数的构造函数时,子类的构造函数必须通过this或者super语句指定要访问的构造函数。
public class OverRideDemo{    public static void main(String[] args){        Student s = new Student();    }}class Person{    Person(){        System.out.println("父类初始化");    }}class Student extends Person{    Student(){        System.out.println("子类初始化");    }}
输出结果为:

这表示子类初始化时,会先初始化父类
父类中无空参构造函数时:
public class OverRideDemo{    public static void main(String[] args){        Student s = new Student(21);    }}class Person{    Person(int age){        System.out.println("父类初始化 "+age);    }}class Student extends Person{    Student(int age){        super(age);    //父类中无空参构造函数时,要指定使用哪个构造函数来初始化父类。        System.out.println("子类初始化");    }}
输出结果:



静态代码块随着类的加载最先初始化

原创粉丝点击