Java日志第10天 2020.7.15
第五章 类的继承和多态
5.1 Java中的继承
子类继承父类的属性和方法,并根据需要增加它为自己的新的属性和方法。由此而得到的类为子类,被继承的类为父类,也叫超类。Java不支持多继承(子类只能有一个父类)。
*5.1.1 Object类及其方法
Java中的所有类都默认继承Object类,Object是Java所有类的父类。
定义:public class Object
*5.1.2 对象中的克隆
Java克隆是Java语言的特性之一,在实际中应用比较少见。但有时用克隆方法会更方便、更有效率。
(1)克隆的限制
*被克隆的类必须自己实现Cloneable接口,以指示Object.clone()方法可以合法的对该类实例进行按字段赋值。Cloneable接口实际上是个标识接口,没有任何接口方法。
*实现Cloneable接口的类应该使用公共方法重写Object.clone(它是受保护的)。某个对象实现了此接口就克隆它是不可能的。
*在Java.lang.Object类中克隆方法是这么定义的。
protected Object clone()
throws CloneNotSupportedException
(2)浅层克隆和深层克隆
*浅层克隆:主要复制基本对象的值
*深层克隆:当类存在聚合关系是,克隆就必须考虑聚合对象的克隆。可以复制引用类型的字段。
示例:浅层克隆
public class CloneDemo {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person p = new Person("任我行", 35);
        Person p2 = (Person)p.clone();
        System.out.println("克隆前:"+p.getName()+","+p.getAge());
        System.out.println("克隆后:"+p2.getName()+","+p2.getAge());
        if(p == p2){
            System.out.println("p和p2的地址相等!");
        } else{
            System.out.println("p和p2的地址不相等!!");
        }
        
    }
}
/*简单类克隆实现
要实现克隆,必须实现Cloneable接口,这是一个标识接口,没哟接口方法
实现了Cloneable接口,以指示Object.clone()方法
可以合法地对该类实例进行按字段复制
按照惯例,实现此接口的类应该使用公共方法重写Object.clone(它是受保护的)
 */
class Person implements Cloneable{
    private String name;
    private int age;
    public Person(String name, int age){
        this.name=name;
        this.age=age;
    }
    public String getName(){
        return name;
    }
    public void setName(String name){
        this.name=name;
    }
    public int getAge(){
        return age;
    }
    public void setAge(int age){
        this.age=age;
    }
    @Override
    protected  Object clone() throws CloneNotSupportedException{
        return super.clone();
    }
}

示例:深层克隆
public class CloneDeepDemo {
    public static void main(String[] args) throws CloneNotSupportedException{
        Person per = new Person("令狐冲",20);
        P p = new P(per);
        P p2 =(P)p.clone();
        System.out.println("克隆前:"+p.getPer().getName()+","+p.getPer().getAge());
        System.out.println("克隆后:"+p2.getPer().getName()+","+p2.getPer().getAge());
        if(p==p2)
            System.out.println("p和p2的地址相等!");
        else
            System.out.println("p和p2的地址不相等!");
        if(p.getPer()==p2.getPer())
            System.out.println("p中的Person对象与p2中的Person对象相等!");
        else
            System.out.println("p中的Person对象与p2中的Person对象不相等!");
    }
}
class P implements Cloneable{
    Person per;
    public P(Person per){
        this.per = per;
    }
    public Person getPer(){
        return per;
    }
    public void setPer(Person per){
        this.per = per;
    }
    @Override
    protected  Object clone() throws  CloneNotSupportedException{
        P p  = (P)super.clone();
        p.per = (Person)this.per.clone();
        return p;
    }
}

5.1.3 Java的继承
Java中的继承使用关键字“extends”表示,
公式:class 子类 extennds 父类 {}
使用继承子类可以拥有父类中的非私有属性
示例:
定义一个Person类
public class Person {
        public String name;
        public String sex;
        public int age;
        public String getName(){
            return name;
        }
        public void setName(String name){
            this.name=name;
        }
        public String getSex(){
            return sex;
        }
        public void setSex(String sex){
            this.sex=sex;
        }
        public int getAge(){
            return age;
        }
        public void setAge(int age){
            this.age=age;
        }
}
定义Student类继承Person类
public class Student extends Person {
    private String deparetment;//系别
    private String specialty;//专业
}
public class day06 {
    public static void main(String[] args) {
        Student s = new Student();
        //子类共享父类中的非私有属性
        String str=s.name;
        //子类可以拥有父类中的非私有方法
        s.setName("伍正云");
        s.setAge(25);
    }
}
*Java不支持不支持多继承,一个类只能继承一个类,即子类只能继承一个父类,但是一个父类可以被多个子类继承。
5.1.4 super关键字
在Java继承中,子类可以使用super富案件自调用父类的非私有属性和非私有方法,还可以调用父类的非私有构造方法。
(1)使用super关键字调用父类属性
public class Person {
        public String name;
        public String sex;
        public int age;
        public String getName(){
            return name;
        }
        public void setName(String name){
            this.name=name;
        }
        public String getSex(){
            return sex;
        }
        public void setSex(String sex){
            this.sex=sex;
        }
        public int getAge(){
            return age;
        }
        public void setAge(int age){
            this.age=age;
        }
}
public class Student extends Person {
    private String deparetment;//系别
    private String specialty;//专业
    String name1 = super.name; //调用父类的属性name
    public void test(){
        super.getAge(); //调用父类方法
    }
}
*super关键字可以省略
public class Student extends Person {
    private String deparetment;//系别
    private String specialty;//专业
    String name1 = name; //调用父类的属性name
    public void test(){
       getAge(); //调用父类方法
    }
}
(2)使用super调用父类的构造方法
public class Person {
        private String name;
        private int age;
        public Person(){
            
        }
        public Person(String name, int age){
            this.name = name;
            this.age = age;
        }
}
class Student extends Person{
    public Student(){
        super("sky",26);
    }
}
(3)子类和父类构造方法的执行顺序
*子类默认调用父类的无参构造方法,也就是说,子类的构造方法中会默认调用super(),并且在构造方法的第一行。
*如果子类只提供有参的构造方法,则必须在子类的构造刚发中调用父类的构造方法。
*执行父类的构造方法后,在调用本类中的构造方法。
public class Person {
        private String name;
        private int age;
        public Person(){
            System.out.println("父类无参构造方法");
        }
        public Person(String name, int age){
            this.name = name;
            this.age = age;
            System.out.println("父类有参构造方法");
        }
        public static void main(String[] args){
            Student stu = new Student();
        }
}
class Student extends Person{
    public Student(){
        super("sky",26);
        System.out.println("子类有参构造方法");
    }
}
![]()
5.2 多态变化
5.2.1 Java中多态的实现
覆盖:子类重写父类中的方法
public class Father {
    public void say(){
        System.out.println("Father say()");
    }
    public static void main(String[] args) {
        Son son = new Son();
        son.say();
    }
}
class Son extends Father{
    public void say(){
        System.out.println("Son say()");
    }
}

5.2.2 类型检测——向上转型/向下转型
向上转型是指父类对象的引用指向子类对象。向下转型是指在向上转型的基础上再次指向子类对象。
(1)向上转型
语法:父类 对象 = new 子类()
public class Father {
    public void say(){
        System.out.println("Father say()");
    }
    public static void main(String[] args) {
        //向上转型
        Father son = new Son();
        son.say();
    }
}
class Son extends Father{
    public void say(){
        System.out.println("Son say()");
    }
}
![]()
有时使用向上转型会丢失掉子类特有的方法
public class Father {
    public void say(){
        System.out.println("Father say()");
    }
    public static void main(String[] args) {
        //向上转型
        Father son = new Son();
        son.sayMe();//报错
    }
}
class Son extends Father{
    public void say(){
        System.out.println("Son say()");
    }
    public void sayMe(){
        System.out.println("Son sayMe()");
    }
}
 
(2)向下转型
语法:    父类 对象1 = new 子类()
    子类 对象2 = (子类)对象1
public class Father {
    public void say(){
        System.out.println("Father say()");
    }
    public static void main(String[] args) {
        //向上转型
        Father son = new Son();
        //向下转型
        Son son2 = (Son)son;
        son2.sayMe();//报错
    }
}
class Son extends Father{
    public void say(){
        System.out.println("Son say()");
    }
    public void sayMe(){
        System.out.println("Son sayMe()");
    }
}
如果直接将父类强转成子类对象会报错
public class Father {
    public void say(){
        System.out.println("Father say()");
    }
    public static void main(String[] args) {
        Father f = new Father();
        Son son = (Son)f;
    }
}
class Son extends Father{
    public void say(){
        System.out.println("Son say()");
    }
    public void sayMe(){
        System.out.println("Son sayMe()");
    }
}

5.2.3 动态绑定
*动态绑定
会基于对象实际的类型(只能在运行时得知)来选择所调用的方法
*静态绑定
在程序编译时就绑定的,在Java中的变量都是静态绑定的,只有private、static和final是静态绑定的。



 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号