(代码块;继承;this与super关系;继承关系中构造方法和成员方法的关系;重载与重写对比;类的继承特点;final关键字;)Java零基础学习笔记 Day08

旧时模样 提交于 2020-03-02 14:33:13

一,代码块

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

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

代码

package com.ujiuye.demo;
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.执行时机:创建对象的的时候就执行。

代码

package com.ujiuye.demo;

public class Dog {
    String name;
    int age ;        //空参构造public Dog() {
        super();
        System.out.println("空参构造执行了");
    }       //构造代码块    {        name = "花花";        age = 4;        System.out.println("构造代码块执行");
    }
}    //测试类
 package com.ujiuye.demo;
 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 {代码段}
  • 执行特点: 随着类的加载而加载,只加载一次【只执行一次

代码示例

package com.ujiuye.demo;

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("静态代码块执行了");
    }
}   //测试类
package com.ujiuye.demo;

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
构造代码块执行了

 

  • 案例:
  • 验证代码块之间和构造方法的执行顺序【典型的面试题】
package com.ujiuye.demo;
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;
    }
    
}    //测试类
package com.ujiuye.demo;
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类
package com.ujiuye.demo;public class Mouse {
    String name;
     int age;
     public void eat() {
         System.out.println("老鼠吃药");
     }
}//Cat类
package com.ujiuye.demo;
public class Cat {
     String name;
     int age;
     public void eat() {
         System.out.println("猫吃鱼");
     }
}//Pig类
package com.ujiuye.demo;
public class Pig {
    String name;
     int age;
     public void eat() {
         System.out.println("猪吃饲料");
     }
}//没有继承的时候每个类的属性都要写一遍

 

有继承,代码:
//父类package com.ujiuye.demo;
public class Home_Animal {
    String name;
    int age;
    String color;
}
package com.ujiuye.demo;
public class Mouse extends Home_Animal { //子类继承父类
     public void eat() {
         System.out.println("老鼠吃药");
     }
}
package com.ujiuye.demo;
public class Cat extends Home_Animal{ //子类继承父类
     public void eat() {
         System.out.println("猫吃鱼");
     }
}
package com.ujiuye.demo;
public class Pig extends Home_Animal{ //子类继承父类
     public void eat() {
         System.out.println("猪吃饲料");
     }
}
  • 弊端:

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

  1. ​子父类中属性名不同名:父类对象只能使用父类中的变量【属性】,子类对象既能使用子类自己里面的属性也可以使用父类中的属性
  2. ​子父类中属性名同名
    父类对象只能使用父类自己的,子类对象优先使用自己的同名属性,非要使用父类的同名属性,
    使用关键字super来使用父类的同名属性,父类永远使用的是自己的属性,子类自己的和父类他都可以使用
代码:
//父类package com.ujiuye.demo;
public class Father {
    int a = 10 ;
    int b = 20 ;
}//子类
package com.ujiuye.demo;
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 值
    }
}//测试类
package com.ujiuye.demo;
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:代表当前调用对象的父类

代码示例

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();执行你调用的那个父类构造

练习

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

代码示例:

 // 父类  package com.ujiuye.demo;
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
package com.ujiuye.demo;
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
package com.ujiuye.demo;
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;
    }
}//测试类
package com.ujiuye.demo;
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 (覆盖 覆写) 编译器编译时检查重写的格式、时机等是否正确。
  • 重写好处:可以对父类的功能进行修改或增强。

代码

//父类package com.ujiuye.demo;
public class Car {    //写了两个方法
    public  void  show() {
        System.out.println("这是一辆车");
    }
    public  void  print() {
        System.out.println("这是一辆老牛车");
    }
}//子类
package com.ujiuye.demo;
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修饰的内容:修饰类、属性、方法
  • 修饰类:最终类,不能够被继承

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

//父类package com.ujiuye.demo;
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;
    }
}//子类
package com.ujiuye.demo;
public class Men_Son extends Men{//men 报错,不让继承 
}

 

  • 修饰变量:变量的值就变成最终的值,不能够再 改变。
  • ​ 特点:值不会发生改变了,变相理解为是常量
  • ​ 注意点:final 修饰的变量只能赋值一次,不能第二次赋值。
package com.ujiuye.demo;
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只能赋值一次,第二次赋值报错
    }     
}

 

  • 修饰方法
  • ​ 特点:不能够被子类重写,但是可以被调用【子父类都可以调用】
//父类package com.ujiuye.demo;
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上山打老虎");
    }        
}//子类
package com.ujiuye.demo;
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(); //可以被调用
    }
}

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!