Java代码块、继承、方法重写与重载、final关键字

Java代码块、继承、方法重写与重载、final关键字

一、代码块

  • 概述:在Java中,使用{}括起来的代码被称为代码块

  • 分类

    • 局部代码块:在方法中出现;限定变量生命周期,及早释放,提高内存利用率
    • 构造代码块:在类中方法外出现;多个构造方法方法中相同的代码存放到一起,每次调用构造都执行,并且在构造方法前执行
    • 静态代码块:在类中方法外出现,并加上static修饰;用于给类进行初始化,在加载的时候就执行,并且只执行一次
    • 同步代码块(多线程部分)
  • 案例

    看程序写结果
    	class Student {
    		//静态代码块只执行一次
    		static {
    			System.out.println("Student 静态代码块"); //3
    		}
    		
    		{
    			System.out.println("Student 构造代码块"); //4 6
    		}
    		
    		public Student() {
    			System.out.println("Student 构造方法"); //5 7
    		}
    	}
    
    	class StudentDemo {
    		static {
    			System.out.println("StudentDemo的静态代码块");//1
    		}
    		
    		public static void main(String[] args) {
    			System.out.println("我是main方法");//2
    			
    			Student s1 = new Student();
    			Student s2 = new Student();
    		}
    	}
    

二、继承

  • 概述:多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可,单独的这个类称为父类,基类或者超类;这多个类可以称为子类或者派生类

  • 格式:class 子类名 extends 父类名{}

  • 案例

    //父类
    public class Animal {
        String name;
        int age
        public void eat() {
            System.out.println("吃饭");
        }
        public void sleep() {
            System.out.println("睡觉");
        }
    }
    
    //子类
    public class Cat extends Animal{
        public void catcheMouse(){
            System.out.println("抓老鼠");
        }
    }
    
    //子类
    public class Dog extends Animal{
        public void lookDoor() {
            System.out.println("看门");
        }
    }
    
  • 继承的好处:提高了代码的复用性和维护性,让类与类之间产生了关系,是多态的前提

  • 继承的弊端:增加了耦合性,让类跟类之间产生了关系

  • 软件的设计的原则:高内聚,低耦合

    • 内聚:一个类单独完成某个功能的能力
    • 耦合:一个类要完成某个功能,得去依赖某些类
  • 继承的特点:Java只支持单继承,但支持多层继承(格式:extends 类1,类2)

  • 继承的注意事项

    • 子类只能继承父类所有非私有的成员(成员方法和成员变量)
    • 子类不能继承父类的构造方法,但是可以通过super关键字去访问父类构造方法。
    • 不要为了部分功能而去继承
  • 继承使用场景

    继承体现了“is a”的关系,如果B是A的中就可以考虑使用继承

  • 继承中成员变量的关系

    当子类与父类中成员变量不同名时直接找该变量使用,当子父类中成员变量名称一样时,遵循就近原则,即,先在子类的方法局部范围找,有就使用,没有就在子类的成员方法找,如果没有就在父类的成员范围找,如果还没找到就报错

  • 继承中构造方法的关系

    • 子类中所有的构造方法默认都会访问父类中空参数的构造方法,因为子类会继承父类中的数据,可能还会使用父类的数据。所以,子类初始化之前,一定要先完成父类数据的初始化。每一个构造方法的第一条语句默认都是:super()

    • 父类没有无参构造方法,子类怎么办
      a: 在父类中添加一个无参的构造方法
      b:子类通过super去显示调用父类其他的带参的构造方法
      c:子类通过this去调用本类的其他构造方法

    • 注意:

      • 本类其他构造也必须首先访问了父类构造
      • super(…)或者this(….)必须出现在第一条语句上
    • 案例

      class Fu {
      		static {
      			System.out.println("静态代码块Fu"); //1
      		}
      
      		{
      			System.out.println("构造代码块Fu"); //3
      		}
      
      		public Fu() {
      			System.out.println("构造方法Fu"); //4
      		}
      	}
      
      	class Zi extends Fu {
      		static {
      			System.out.println("静态代码块Zi"); //2
      		}
      
      		{
      			System.out.println("构造代码块Zi"); //5
      		}
      
      		public Zi() {
      			System.out.println("构造方法Zi"); //6
      		}
      	}
      	
      	class Test(){
              public static void main(String[] args){
                  Zi z = new Zi();
              }
      	}
      	//执行结果顺序见上注释
      
  • 继承中成员方法关系

    • 当子类的方法名和父类的方法名不一样的时候直接调用该方法
    • 当子类的方法名和父类的方法名一样的时候
      a: 先查找子类中有没有该方法,如果有就使用
      b:在看父类中有没有该方法,有就使用
      c: 如果没有就报错
  • this和super的区别和应用

    • this 代表的是本类对象的引用

    • super代表的是父类存储空间的标识(可以理解成父类的引用,可以操作父类的成员)

    • 调用规则

      a:调用成员变量
      this.成员变量 调用本类的成员变量
      super.成员变量 调用父类的成员变量
      b:调用构造方法
      this(…) 调用本类的构造方法
      super(…) 调用父类的构造方法
      c:调用成员方法
      this.成员方法 调用本类的成员方法
      super.成员方法 调用父类的成员方法

    • 案例

      	class Fu{
      		public int num = 10;
      		public Fu(){
      			System.out.println("fu");
      		}
      	}
      	class Zi extends Fu{
      		public int num = 20;
      		public Zi(){
      			System.out.println("zi");
      		}
      		public void show(){
      			int num = 30;
      			System.out.println(num);//30
      			System.out.println(this.num);//20
      			System.out.println(super.num);//10
      		}
      	}
      	class Test {
      		public static void main(String[] args) {
      			Zi z = new Zi();
      			z.show();
      		}
      	}
      

三、方法重写

  • 概述

    子类中出现了和父类中一模一样的方法声明(方法名,参数列表,返回值类型),也被称为方法覆盖,方法复写

  • 应用

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

  • 注意事项

    a:父类中私有方法不能被重写,因为父类私有方法子类根本就无法继承
    b:子类重写父类方法时,访问权限不能更低,最好一致
    c:父类静态方法,子类也必须通过静态方法进行重写,其实这个算不上方法重写,但是现象确实如此

  • 案例

    //父类
    public class Person {
        public String name;
        public int age;
        public void eat(){
            System.out.println("吃饭");
        }
        public void sleep(){
            System.out.println("睡觉");
        }
    }
    
    //子类
    public class Student extends Person{
        public void palyGame(){
            System.out.println("玩游戏");
        }
        //方法重写
        @Override
        public void eat() {
            System.out.println("学生爱吃麻辣烫");
        }
    
        @Override
        public void sleep() {
            super.sleep();
            System.out.println("我不仅睡觉,还要打呼噜");
        }
    }
    
    //子类
    public class Teacher extends Person {
        @Override
        public void eat() {
            System.out.println("老师爱吃油泼面");
        }
    
        @Override
        public void sleep() {
            System.out.println("我喜欢晚上搂这老婆睡觉");
        }
    	//子类特有方法
        public void sing() {
            System.out.println("唱歌");
        }
    }
    

四、final关键字

由于继承中有一个方法重写的现象,而有时候我们不想让子类去重写父类的方法.这对这种情况java就给我们提供了一个关键字: final

final关键字是最终的意思,可以修饰类,变量,成员方法

  • final修饰特点

    修饰类: 被修饰类不能被继承
    修饰方法: 被修饰的方法不能被重写
    修饰变量: 被修饰的变量不能被重新赋值,因为这个量其实是一个常量(变量为基本类型,值不能改变;变量为引用类型,地址不能被改变)

你可能感兴趣的:(Java基础)