• 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是静态绑定的。
  • 相关阅读:
    使用灰层覆盖UI时,有事发生
    通过自定义ISAPI Filter来禁止敏感文件的访问
    静态链接库LIB和动态链接库DLL的区别 创建和示例
    深入剖析C++中的string类
    .net c# 序列化和反序列
    ASP.NET 状态服务 及 session丢失问题解决方案总结
    IWAM_账号的用途以及如何同步密码
    COM 组件设计与应用(一)起源及复合文件
    两种古老的WEB编程技术 CGI和ISAPI之间的区别
    Send MSMQ Messages Securely Across the Internet with HTTP and SOAP
  • 原文地址:https://www.cnblogs.com/Gazikel/p/13304854.html
Copyright © 2020-2023  润新知