zoukankan      html  css  js  c++  java
  • Day 08Java基础学习笔记

    继承extends(也叫扩展)

    多个类中存在相同的属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。

    通过extends关键字可以实现类的继承
        class 子类名 extends 父类名{}
    

    继承的案例

    创建一个Person类,定义两个功能吃饭、睡觉,再创建学生类、教师类,继承Person类,再定义两个自己独有的功能
    创建Persen类
    public class Person {
        public void eat(){
            System.out.println("吃饭");
        }
        public void sleep(){
            System.out.println("睡觉");
        }
    }
    //创建子类学生类继承Person类
    public class Student extends Person {
        public void play(){
            System.out.println("打游戏");
        }
    }
    //创建Teacher类继承Person类
    public class Teacher extends Person {
        public void teach(){
            System.out.println("教书");
        }
    }
    //创建测试类,对继承进行测试
    public class PersonExtends {
        public static void main(String[] args) {
            Student st = new Student();
            st.eat();   //用学生类调用继承方法
            st.play();  //调用自己的方法
            Teacher t =new Teacher();
            t.sleep();
            t.teach();
        }
    }
    

    继承的好处

    • 提高了代码的复用性:多个类的相同成员可以放到一个类中

    • 提高了代码的维护性:如果功能的代码需要修改,修改一处即可,继承的类中自动都被修改了

    • 让类与类之间产生了关系,是多态的前提

    Java中继承的特点

    Java只支持单继承,不支持多继承

    即一个类只能有一个直接父类,不可以有多个直接父类

        正确写法:class Sub extends Demo{}
        错误写法:class Sub extends Demo1,Demo2{}
    
    Java支持多层继承
        class A{}
        class B extends A{}
        class C extends B{}
        例
        //
        public class Grandfather {
            public void show(){
                System.out.println("grandfather");
            }
        }
        public class Father extends Grandfather {
            public void method(){
                System.out.println("father");
            }
        }
        public class Son extends Father {
            public void function(){
                System.out.println("son");
            }
        }
        //测试类
        public class GrandfatherTest {
            public static void main(String[] args) {
                Son s = new Son();
                s.function();
                s.method();
                s.show();
            }
        }
    

    Java中继承的注意事项

    1. 子类只能继承父类中所有非私有的成员(成员变量、成员方法)
    2. 子类不能父类的的构造方法,但可以同super关键字去访问父类构造方法
    3. 不要为了部分功能去继承,如果有两个类A,B,只有他们符合A是B的一种或者B是A的一种,就可以考虑使用继承

    继承中成员变量的关系

    案列演示:
    //创建父类定义成员变量
    public class Field {
        int num = 10;
        public void method(){
            System.out.println(num);
        }
    }
    //创建子类继承父类,并定义与父类同名成员变量
    public class FieldExtends extends Field {
        int num = 15;
        public void show(){
            System.out.println(num);
        }
        //在子类中定义新的方法,在方法内再定义与父类成员变量同名变量
        public void function(){  
            int num = 5;
            System.out.println(num);
        }
    }
    //测试类
    public class FieldTest {
        public static void main(String[] args) {
            FieldExtends fe = new FieldExtends();
            fe.show();  // 15
            fe.function();   // 5
            fe.method();   //10
        }
    }
    
    通过案列可以知道在子类中访问一个变量的顺序
    1. 在子类方法的局部范围找,有就使用
    2. 在子类的成员范围找,有就使用
    3. 在父类成员范围找有就使用
    4. 如果找不到,就报错

    super关键字

    用法与this关键字类似

    • this 代表对本类对象的引用
    • super 代表父类存储空间的标识(可以理解为对父类对象的引用)

    用法

    • 访问成员变量

      this.成员变量
      super.成员变量(访问父类的成员变量,不能访问父类的private变量)
      访问静态成员时,也可以用  父类名.静态成员
      
    • 访问构造方法

      this(...)  super(...)
      
    • 访问成员方法

      this.成员方法()  super.成员方法()
      
    案列演示
        //创建父类
        public class FatherSuper {
            int num = 10;
            public FatherSuper(){
                System.out.println("父类构造方法");
            }
            public void show(){
                System.out.println("父类成员方法");
            }
        }
        public class SonSuper extends FatherSuper {
            int num = 15 ;
            public SonSuper(){
                System.out.println("子类构造方法");
            }
            public void method(){
                System.out.println("子类成员方法");
            }
            public void function(){
                int num = 5;                    
                System.out.println(num);        //打印方法内局部变量
                System.out.println(super.num);  //打印父类成员变量
                System.out.println(this.num);   //打印本类成员变量
                super.show();                   //调用父类成员方法
                this.method();                  //调用本类成员方法
    
            }
        }
        测试类
        public class SuperTest {
            public static void main(String[] args) {
                SonSuper ss = new SonSuper();
                ss.function();
            }
        }
    

    继承中构造方法的关系

    1. 子类中所有的构造方法默认都会访问父类中空参数的构造方法,除非显示使用super/this调用了父类或者本类的其他构造方法。
    2. 在类中对本类或者父类构造方法的调用,只能在构造方法中,不能在实例方法总中调用构造方法(更不能在类方法中调用构造方法)
    注意构造方法不能递归调用
        class A {
            public A(int i){
                this(1 ,2);
            }
            public A(int a ,int b){
                this(2);
            }
        }
    

    案例演示

        //创建父类
        public class A {
            public A(){
                System.out.println("父类空参构造");
            }
            public A(String name){
                System.out.println("父类有参构造");
            }
        }
        //创建子类继承父类  
        public class B extends A {
            public B(){           //这一步默认执行了  super();调用了父类空参
                System.out.println("子类空参构造");
            }
            public B(String name){
                super(name);  //调用父类有参构造方法
                System.out.println("子类有参构造");
            }
        }
        测试类
        public class C {
            public static void main(String[] args) {
                B b = new B();
                B b1 = new B("tom");
            } 
        }   
    
    如果父类没有空参构造,子类的构造方法中就必须显式调用父类带参构造super(...);
    super(…)或者this(…)必须出现在构造方法第一条语句上否则,就会有父类数据的多次初始化

    方法重写

    子类中出现和父类中一摸一样的方法声明,称为方法覆盖(Override)或重写(OverWrite)

    使用特点

    • 如果方法名不同就调用对应的方法
    • 如果方法名相同最终使用的是自己的(使用子类的引用的时候,在多态情况下,使用父类的引用,则有可能调用的是父类静态方法)

    方法重写的应用

    • 当子类需要父类功能时,而功能主体子类有自己的特有的内容时,可以重写父类的方法,这样即沿袭了父类的功能,又定义了特有的内容。
    • 方法重写是多态实现的条件

      //首先创建 一个手机父类
      public class PhoneF {
          public void call(String name){   //定义一个方法
              System.out.println("给"+name+"打电话");
          }
      }
      //在创建一个手机子类继承父类
      public class PhoneS extends PhoneF {
          public void call(String name){   //同名同修饰词   对父类中的方法进行重写
              super.call(name);
              System.out.println("听天气预报");  //在继承父类之后在身再加的打印语句
          }
      }
      //创建测试类
      public class PhoneTest {
          public static void main(String[] args) {
              PhoneS ps = new PhoneS();
              ps.call("Tom");
          }
      }
      

    方法重写的注意事项

    • 父类中私有的方法不能被重写,编译报错;
    • 子类重写父类方法时,访问权限不能更低,编译报错;
    • 子类重写父类方法时,返回值类型可以相同,也可以是父类返回值的子类型;
    • 父类的实例方法(非静态方法),子类不能重新定义为静态方法
    • 子类中的重写父类方法,按照重写的原则(访问权限不能变小,返回值类型同类或者为子类,方法名相同,形参列表相同);
    • 子类想重写父类的方法,最好是让方法的签名一模一样;

    final关键字

    final关键字是最终的意思,可以修饰类,成员变量,成员方法 - 修饰类,类不能被继承(不能放在extends后面) - 修饰变量,变量将变成常量只能被赋值一次,不论是在子类还是本类中,都不能被修改(常量一般是大写字母表示 final int ONE = 1) - 修饰方法,方法不能被重写(子类只用使用权,没有修改权)

    final修饰局部变量
    • 在方法内部,该变量不可以被改变
    • 在方法声明上,基本类型是这个参数的值不能被改变,引用类型,是这个参数只想的地址值不能被改变

    总结

    类中非static的final变量(实例final变量)可以在生命的时候赋值,如果声明的时候没有赋值的话,就必须在以下两个地方赋值,一个是构造代码块一个是构造方法中,如果这两个地方没有赋值,编译报错。

    如果是static修饰的final变量的话,则只能在两个地方赋值,声明的时候,或者在静态代码块中。

    多态(polymorphism)

    某一个事物,在不同时刻表现出来的不同状态

    在Java中,对一个事物的引用可以分成两种类型,一种是编译时的类型,一种是运行时的类型。 编译时的类型指的是声明这个变量时指定的类型;运行时类型指的是实际赋给这个变量的对象的类型。

        若Student类继承自Person类,则下面的写法是正确的
        Person p = new Student();
    
    注意

    父类引用不能调用子类特有的方法,因为使用了父类的引用,就代表站在父类角度来看待当前子类对象,只能看到从父类继承而来的特性,或者是子类重写的父类的方法。成员变量没有多态性,只能看到父类的成员变量。

    多态中的成员访问特点

    • 成员变量 编译看左边,运行看右边;
    • 构造方法 创建子类对象的时候,访问父类的构造方法,对父类的数据进行初始化
    • 成员方法 便宜看左边,运行看右边
    • 静态方法 编译看左边,运行看右边

    多态的前提条件

    • 有继承关系
    • 有方法重写
    • 有父类引用指向子类对象

    多态中成员访问特点

    成员变量和静态方法没有多态性 只有被子类重写的成员方法才有多态性

  • 相关阅读:
    【每天都要看一下】
    【这里有别人的经验,也有好玩的发现】
    【WPF】Listbox模板内button点击选中当前listboxItem
    【WFP】弹出窗口不在win10 任务列表里显示的方法
    PSD路径转换为 WPF path 的data
    【WPF】Listbox内item的样式替换默认选中样式和鼠标滑过样式
    【WPF】ListBox1内嵌套ListBox2 2的滑轮滚动阻止1的滚动解决方法
    【C#】文本框拼音检索汉字
    【WPF】Datagrid显示最低下一跳
    【C#】绝对随机数
  • 原文地址:https://www.cnblogs.com/740810wt/p/6618034.html
Copyright © 2011-2022 走看看