zoukankan      html  css  js  c++  java
  • 代码块;继承;this与super关系;重载与重写对比;类的继承特点;final关键字 (Java Day08)

    一,代码块

    • 概述:被大阔号单独包裹的代码段叫做代码块
    • ​根据位置的不同,命名的不同他的使用时机和功能不一样。
    • 分类:
    1. ​ 局部代码块
    2. ​ 构造代码块
    3. ​ 静态代码块
    4. ​ 同步代码块【今天不讲,多线程的时候讲】

    • 局部代码块
    1. ​ 概述:定义在方法中的代码块
    2. ​ 位置:类中方法的方法体中
    3. ​ 作用:给局部变量赋值,或者定义局部变量

    代码

    
    import java.util.Arrays;
    public class Demo01 { public static void main(String[] args) { Demo01 demo01 = new Demo01(); demo01.show(); } public void show() { int a = 10 ;//局部变量 //局部代码块 { a = 30 ; int b = 40;//局部变量 System.out.println(a);//30 10 System.out.println(b);//40 } System.out.println(a);//30 代码块对外面的局部变量的赋值是永久的 //System.out.println(b);输出不了 b变量的生存范围变小了 } }
    • 总结:
    • 好处:缩小了局部变量的使用范围和生命周期,及时的释放内存空间达到提升运行效率。
    • 注意:
    1. ​ 局部代码块可以使用外部的局部变量,但是外部不能使用代码块内部的局部变量
    2. ​ 局部代码块内部的局部变量的生命周期比外面的局部变量短,随着代码块的执行完毕就消失了,而外部的局部变量随着方法的执行完毕而消失
    3. ​ 局部代码块定义变量的时候不能和外面的变量重名
    • 执行时机:方法被调用

    • 构造代码块

    • 概述:定义在成员位置的代码块
    • ​位置:属性位置【类中方法外】
    • 作用:给类的属性赋值
    • 特点:
      1.可以给成员属性赋值
      2.每次创建对象的时候他都会执行一次
      3.构造方法执行前他先执行。
      4.执行时机:创建对象的的时候就执行。

    代码

    public class Dog {
        String name;
        int age ;

    //空参构造
    public Dog() {
            super();
            System.out.println("空参构造执行了");
        }


    //构造代码块
    {
    name = "花花";
    age = 4;
    System.out.println("构造代码块执行");
        }
    }

    //定义测试类
     public class Dog_Test {
        public static void main(String[] args) {
            Dog dog = new Dog();//调用空参构造创建对象
            System.out.println(dog.name);//null 花花 
            System.out.println(dog.age);//0  4
        }
    }
    =====================================================
    结果:
    构造代码块执行 
    空参构造执行了
    花花
    4
    • 静态代码块

    • 概述:被static修饰的构造代码块更名为静态代码块
    • 位置:成员属性位置【类中方法外】
    • 作用:给静态变量赋值,用于配置程序的环境变量。
    • 格式: static {代码段}
    • 执行特点: 随着类的加载而加载,只加载一次只执行一次

    代码示例

    public class Person {
        String name;
        int age;
        static String country;
        //构造代码块
        {
            name = "宝宝";
            age = 39;
            country = "japan";
            System.out.println("构造代码块执行了");
        }
        //静态代码块 只能给静态变量赋值
        static {
            //name = "宝宝";
            //age = 39;
            country = "China";
            System.out.println("静态代码块执行了");
        }
    }
    //测试类
    public class Person_Test { public static void main(String[] args) { System.out.println(Person.country); //China 静态代码块可以直接调用不用创建对象 Person person = new Person(); //构造代码块需创建对象再调用 System.out.println(person.name);//宝宝 System.out.println(person.age);//39 System.out.println(person.country);//japan Person person2 = new Person(); } }
    ===========================================================
    结果: 静态代码块执行了 China 构造代码块执行了 宝宝
    39 japan 构造代码块执行了
    • 案例:
    • 验证代码块之间和构造方法的执行顺序【典型的面试题】
    public class Animal {
        int age ;
        static  String name;
        //构造代码块
        {
            System.out.println("构造代码块执行了"); // 3  6
        }
    //静态代码块
    static{ System.out.println("静态代码块执行了"); // 2 }
    //有参构造
    public Animal(int age) { super(); this.age = age; System.out.println("有参构造执行了");// 7 }
    //空参构造
    public Animal() { super(); System.out.println("空参构造执行了");// 4 }
    // getter/setter 方法
    public int getAge() { return age; } public void setAge(int age) { //局部代码块 { System.out.println("局部代码块执行了"); // 5 8 } this.age = age; } public static String getName() { return name; } public static void setName(String name) { Animal.name = name; } }
    //测试类
    public class Animal_Test { static { System.out.println("测试类的静态代码块"); // 1 } public static void main(String[] args) { Animal animal = new Animal(); //创建对象调用构造代码块,
    每次创建对象的时候他都会执行一次,()表述空参
    animal.setAge(13);
    Animal animal2 = new Animal(56); //(56)表示有参
    animal2.setAge(23); } }
    =============================================================
    结果:
    测试类的静态代码块
    --> 1
    静态代码块执行了
    --> 2
    构造代码块执行了
    --> 3
    空参构造执行了
    --> 4
    局部代码块执行了
    --> 5
    构造代码块执行了
    --> 6
    有参构造执行了
    --> 7
    局部代码块执行了
    --> 8
    • 注意:

    ​             1、优先执行静态代码块【只执行一次】【先加载哪个类就先执行哪个静态代码块;测试类要优先其他类,其他类根据代码的书写顺序自左往右自上而下的依次执行】

    ​             2、创建对象的时候先执行构造代码块 再执行构造方法

    ​             3、对象调用方法的时候会执行方法中的内容【局部代码块】

    ​             4、再一次创建对象先执行构造代码块 再执行构造方法【就不会去执行静态的代码块】

    二,继承

    • 概述:子承父业就叫做继承。在java中父类中的资源可以被子类使用,子类中的资源不能被父类使用;父类往往里面放的是所有子类共性的资源。
    • ​java中的类和类【事物于事物之间】有关系吗?本身是没有关系,继承说明类和类之间要发生关系,想办法让类和类之间产生继承关系。
    • 关键字:extends 可以把两个不相关的类产生父子关系
    • ​格式: class 类A【子类】名称 extends 类B【父类名称】 {A的内容}
    • ​前提:父类必须存在。
    • 好处:

                1、代码的复用性提升。

                2、利于代码的维护性。[ 方便修改 ]

                3、是多态的前提。增加代码的扩展性。

    无继承,代码:

    //Mouse类
    public class Mouse {
        String name;
         int age;
         public void eat() {
             System.out.println("老鼠吃药");
         }
    }
    //Cat类public class Cat { String name; int age; public void eat() { System.out.println("猫吃鱼"); } }

    //Pig类public class Pig { String name; int age; public void eat() { System.out.println("猪吃饲料"); } }
    //没有继承的时候每个类的属性都要写一遍
    有继承,代码:
    //父类
    public class Home_Animal { String name; int age; String color; } public class Mouse extends Home_Animal { //子类继承父类 public void eat() { System.out.println("老鼠吃药"); } } public class Cat extends Home_Animal{ //子类继承父类 public void eat() { System.out.println("猫吃鱼"); } } public class Pig extends Home_Animal{ //子类继承父类 public void eat() { System.out.println("猪吃饲料"); } }
    • 继承注意点:
    1. 继承关系必须符合is a 要求,is a 就是子类必须是父类的一个特例。[子类是否可以继承父类里面的所有的功能]
    2. 子类不能使用父类私有的成员
    3. 继承关系的代码提高耦合,降低内聚。
      设计模式:1)装饰者设计模式         2)代理设计模式(第三阶段   spring)
    • 继承特性:
    1. 单根性:一个子类只能继承一个父类。
    2. 传递性:子类继承父类,父类继承祖类。就是子类可以同时使用父类和祖类的成员。
    • 弊端:

    1. ​ 弊端:类和类之间的关系变强,耦合性强
    2. ​ 耦合性:事物和事物之间的依赖关系的程度
    3. ​ java开发当中:低耦合,高内聚。[ 代码的灵活性降低 ]。
    4. 尽量降低类之间的依赖关系,尽量使用少的对象做多的事情。​ 
    • 继承关系中的成员变量:

    1. ​子父类中属性名不同名:父类对象只能使用父类中的变量【属性】,子类对象既能使用子类自己里面的属性也可以使用父类中的属性
    2. ​子父类中属性名同名
      父类对象只能使用父类自己的,子类对象优先使用自己的同名属性,非要使用父类的同名属性,
      使用关键字 super 来使用父类的同名属性,父类永远使用的是自己的属性,子类自己的和父类他都可以使用
    代码:
    //父类
    public class Father { int a = 10 ; int b = 20 ; }
    //子类
    public class Son extends Father{ //同名变量 int a = 30; //不同名变量 int c = 40; public void show() { System.out.println(this.a);//30 System.out.println(super.a);//10 父类的 a 值 } }
    //测试类
    public class Son_Test { public static void main(String[] args) { Father father = new Father(); Son son = new Son(); System.out.println(father.a);//10 System.out.println(father.b);//20 //System.out.println(father.c);访问不了,父类只能使用自己的变量, c 是子类的变量 System.out.println("================"); System.out.println(son.a);//30 System.out.println(son.b);//子类对象访问父类的属性 20 System.out.println(son.c);//40 //System.out.println(son.a); son.show(); } }
    ==================================================================== 结果:
    10 20 ================ 30 20 40 30 --->子类的a的值 10 --->父类的a的值

    三,this和super的关系

    • ​ this:代表当前调用对象
    • ​ super:代表当前调用对象的父类,里面存储的是父类对象的地址
    1. 存储地址时机:创建子类对象时
    2. 应用:区分子类属性和父类成员   
               super.成员名
               super (参数列表)

    代码示例

    public void show() {
            System.out.println(this.a);//30
            System.out.println(super.a);
        }
            son.show();--->现在是对象son调用show方法this代表了son对象,
                           super代表了son对象对应的父类

    四,继承关系中构造方法的关系:

    • 概述:父类的构造方法子类不能够继承,但是可以间接的使用。父类的构造方法就是创建父类对象的,子类使用的时候只需要创建自己的对象就可以

    ​ 了,不需要创建父类的对象,不用继承父类的构造。【父类的构造子类不继承】

    • 在初始化子类数据之前,必须先完成对父类数据的初始化(因为在初始化子类数据的时候,可能会使用到父类中的数据,所以必须先把父类数据准备好)。

    父类的构造是提供给子类调用的。

    • this和super的理解图

    • 涉及的现象:

                  1、子类在创建对象的时候先初始化父类的相关数据【子类继承父类间接拥有这些数据】

                  2、在子类的构造方法中没有去调用父类的任何的构造方法,系统会默认的添加一个super()【代表父类的空参构造】;默认访问父类的空参构造

                  3、在子类的构造方法中调用了父类的其他的构造方法(),系统就不会添加super();执行你调用的那个父类构造

    练习

    • ​ 定义程序员类和项目经理类
    • ​ 程序员类:属性(姓名、工号、工资)、方法(敲代码)
    • ​ 项目经理类:属性(姓名、工号、工资、奖金)、方法(项目进度控制)
    • 分析:属性中有 一样的属性,可以把一样的属性提取到一个父类中,程序员和经理去继承父类不用再写这些重复的属性,独有的自己写在自己的类中

    代码示例:

     // 父类  
    public class Employee { String name;//姓名 int id;//工号 double salary;
    //空参
    public Employee() { super(); }
    //有参
    public Employee(String name, int id, double salary) { super(); this.name = name; this.id = id; this.salary = salary; } }
    //员工类Coder
    public class Coder extends Employee{ //继承父类 public void work () { System.out.println("工作是敲代码"); }
    //空参构造
    public Coder() { super(); }
    //有参构造
    public Coder(String name, int id, double salary) { super(name, id, salary); } }
    //经理类Manager
    public class Manager extends Employee{ //继承父类 double bonus; public void work() { System.out.println("工作是控制项目进度"); } public Manager(double bonus) { super(); this.bonus = bonus; } public Manager() { super(); } public Manager(String name, int id, double salary) { super(name, id, salary); } public Manager(String name, int id, double salary,double bonus) { super(name, id, salary); this.bonus= bonus; } }
    //测试类
    public class Test { public static void main(String[] args) { Coder coder = new Coder(); System.out.println(coder.id); System.out.println(coder.name); System.out.println(coder.salary); Manager manager = new Manager("大朗", 001, 20, 0); System.out.println(manager.id); System.out.println(manager.name); System.out.println(manager.salary); System.out.println(manager.bonus); } }

    五,继承关系中成员方法的关系:

    • 继承关系中的方法:
    • ​ 方法名不相同:父类对象只能调用父类中的方法,子类对象可以调用自己的方法也可以调用父类的方法
    • ​ 方法名称相同:【子类调用的时候优先执行自己里面的方法】

    ​          1、子类中的方法可以省略不写

    ​          2、子类要更改父类同名方法的方法体

    • 方法的重写:在子父级继承关系中,子类中的方法的返回值类型、方法名、参数列表一模一样,方法体不一样
    • ​ 重写的注解:@Override (覆盖 覆写) 编译器编译时检查重写的格式、时机等是否正确。
    • 重写好处:可以对父类的功能进行修改或增强。

    代码

    //父类
    public class Car {
    //写了两个方法
    public void show() { System.out.println("这是一辆车"); } public void print() { System.out.println("这是一辆老牛车"); } }
    //子类
    public class Bike extends Car{ public void run() { System.out.println("这个车跑起来很快"); } //方法和父类中的方法一模一样 //方法的重写 @Override public void show() { System.out.println("这是一辆自行车"); } }
    • 重写的注意事项:

                 1、父类私有的方法,子类不能够重写【不能继承,就不能重写】

                 2、子类重写的方法要求方法名称、参数列表、返回值类型必须和父类的对应方法一模一样

                 3、子类重写方法的修饰符可以和父类的不一样【private除外】,但是权限要大于等于父类的权限

                 4、父类中被 final 修饰的方法不能够被子类重写

    六,重载和重写的对比:【面试题】

         概念不同;作用不同

    • ​ 重载:

    ​             1、同一个类中

                ​ 2、方法名相同

    ​             3、参数列表不同

    • ​ 重写:

    ​             1、在两个有继承关系的类中【子父类】

    ​             2、方法名相同

    ​             3、参数列表相同

    ​             4、返回值类型相同

    ​             5、修饰符可以不同但是子类的权限大于等于父类的权限

    七,类的继承的特点

    • 继承分类:
    1. ​ 单继承:一个类只能继承另一个类
    2. ​ 多继承:一个类可以同时继承另外的多个类
    3. ​ 多层继承:一个类A继承了类B;类B 有继承类类C

          java中类的继承:支持单继承和多层继承(接口),不支持多继承。

    八,final关键字

    • 概述:他是一个关键字,表示最终的含义。用来修饰相关资源的
    • final修饰的内容:修饰类、属性、方法
    • 修饰类:最终类,不能够被继承

    ​ 类似于古代皇宫里面的太监。

    //父类
    public final class Men { //final修饰的类不给继承 String name; int age;
    //空参构造
    public Men() {
      super(); 
        }
    有参构造
    public Men(String name, int age) { super(); this.name = name; this.age = age; } }
    //子类
    public class Men_Son extends Men{//men 报错,不让继承 }
    • 修饰变量:变量的值就变成最终的值,不能够再 改变。
    • ​ 特点:值不会发生改变了,变相理解为是常量
    • ​ 注意点:final 修饰的变量只能赋值一次,不能第二次赋值。
    public class Demo_final {
        public static void main(String[] args) {
            int a= 10 ;
            final int b = 30;
            final int c ;
        
            a= 20 ;
            //b=40; b报错,因为b被final修饰所以不能够再赋值
            c=50;
            System.out.println(c);
            //c=60; C只能赋值一次,第二次赋值报错
        }     
    }
    • 修饰方法
    • ​ 特点:不能够被子类重写,但是可以被调用【子父类都可以调用】
    //父类
    public class Demo_final { public static void main(String[] args) { int a= 10 ; final int b = 30; final int c ; a= 20 ; //b=40;不能够再赋值 c=50; System.out.println(c); //c=60; } public final void show() { System.out.println("12345上山打老虎"); } }
    //子类
    public class Demo_Zi extends Demo_final{ /*@Override public void show() {//报错了 这个方法父类变为final修饰了 System.out.println("100"); }*/ public static void main(String[] args) { Demo_Zi demo_Zi = new Demo_Zi(); demo_Zi.show(); //可以被调用 Demo_final demo_final = new Demo_final(); demo_final.show(); //可以被调用 } }
  • 相关阅读:
    Java ListIterator(迭代器)
    java 异常 throw
    java iterator(迭代器)
    java list
    type Iterator does not take parameters
    Java 容器的打印
    java 添加一组元素
    Java 容器的基本概念
    软件
    java 学习网站
  • 原文地址:https://www.cnblogs.com/nastu/p/12395290.html
Copyright © 2011-2022 走看看