day02【final、静态、多态】

day02【final、静态、多态】

昨日反馈和回顾
能够写出类的继承格式
    public class 子类 extends 父类{
        
    }
能够说出Java继承的特点
    a.单继承(一个子类只能有一个父类,一个父类可以有多个子类)
    b.多层继承(一个子类可以有一个父类,该父类也可以有自己的父类)
能够说出子类调用父类的成员特点
    如果子父类中有同名的成员变量/成员方法,根据Java就近原则,优先调用子类自己成员
    如果子父类中不同名的成员变量/成员方法,根据变量或者方法名字调用,不存在歧义
    构造方法,a.父类的构造子类无法继承 b.在子类的任何构造第一行,默认调用父类的无参构造,super()
够说出方法重写的概念
    方法重载(overload): 在同一个类中,方法名一样的,参数列表不一样
    方法重写(override): 在继承关系中,子类中有一个和父类除了方法体(权限修饰符),其他一模一样的方法
能够说出this可以解决的问题
    在本类中使用:
		this.xxx  访问本类的成员变量
        this.xxx()    调用本类的成员方法
        this(...) 调用本类的其他构造
         
能够说出super可以解决的问题
     在子类中使用:
		super.xxx	访问父类继承的成员变量
        super.xxx() 调用父类继承的成员方法
        super(...)  调用父类构造方法  
描述抽象方法的概念
     抽象方法: 只有方法的声明,没有方法的实现(加上关键字abstract)
     抽象类: 含有抽象方法的类一定是一个抽象类
         	如果是一个抽象类,其中不一定含有抽象方法     
写出抽象类的格式
     public abstract class 抽象类名{
      	抽象方法
        正常方法    
     }
写出抽象方法的格式
    public abstract void 抽象方法名();
能够说出父类抽象方法的存在意义
    抽象类的意义: 给其他子类继承的,为子类提供模板(模板设计模式)
    抽象方法的意义: 要求子类必须重写(如果不重写,子类还是一个抽象类)    
今日内容介绍
a.关键字final
b.关键字static 
c.引用类型_接口(重点)    

第一章 final关键字

1.1 final关键字
final什么意思: 最终的,不可变的
final在Java中是一个修饰符:
		修饰类,修饰方法,修饰局部变量,修饰成员变量,修饰引用类型变量
1.2 final的作用介绍
  • final修饰类

    final修饰的类,我们称为太监类,不能被继承
    /**
     * 父类
     */
    public final class Fu {
    }
    
    /**
     * 子类报错了,因为父类是final类,不能被继承
     */
    public class Zi extends Fu {
    }
    
    注意: final修饰的类没有子类,并不是说它不能继承别的类
    
  • final修饰方法

    final修饰的方法,不能被重写!! 
    /**
     * 父类
     */
    public class Fu {
        //final修饰方法
        public final void show() {
            System.out.println("show...");
        }
    }
    
    /**
     * 子类
     */
    public class Zi extends Fu{
        //重写报错!!!
        //因为父类的show方法是final修饰的,子类不允许重写
        @Override
        public void show() {
            System.out.println("重写后的show...");
        }
    }
    
  • final修饰局部变量

    final修饰的局部变量,表示该变量只能赋值一次
        
    public class TestDemo {
        public static void main(String[] args) {
            //定义一个局部变量
            //给它加上final修饰
            final int num = 10;
            //报错了!! 因为final修饰的局部变量,只能赋值一次
            num = 20;
            num = 30;
            num = 40;
            System.out.println(num);
        }
    }    
    注意: 
    	final int num = 10;
    		这句代码也可以写出以下两句
        final int num;
    	num = 10;
        	这也是OK的!!
    

    思考:如下两种写法,哪种可以通过编译?

    写法1: 报错!!
    final int c = 0; //只能赋值一次
    for (int i = 0; i < 10; i++) { 
        c = i; // 第二次赋值了,报错!!!
        System.out.println(c); 
    }
    
    写法2: 编译通过!
    for (int i = 0; i < 10; i++) { 
        final int c = i; //c也是final修饰的
        				//因为c是在循环体中定义的,每次循环都是新的一个c
        System.out.println(c); 
    }
    
  • final修饰引用类型的变量

    final修饰引用类型的变量,表示该引用类型变量中保存的地址值不能改变量
    public class Dog {
        int age = 10;
        String name = "旺财";
    }
    public class TestDog {
        public static void main(String[] args) {
            //1.创建一个引用类型的变量
            // 给引用类型的变量也叫上final
            final Dog d = new Dog(); // d中是对象的地址 0x111
    		//报错的!!!!因为final修饰d,表示d中地址值不能改变
            d = new Dog(); //将d中的对象地址 改为 0x222
        }
    }    
    注意:
    	final修饰d只表示d中地址不能改变,并不代表d中的成员变量值不能改变,
    	以下写法是正确的:
    		d.age = 20;
            d.name = "来福";
    
  • final修饰成员变量

    final修饰的成员变量,只能赋值一次,必须赋值
    但是赋值可以有两种选择:
    	a.定义该成员变量的时候赋值
         public class Student {
            //使用final修饰成员变量
            final int age = 10;
        }
       
            
        b.或者在构造方法中给该成员变量赋值  
         public class Student {
            //使用final修饰成员变量
            final int age;
            //在构造方法中赋值
            public Student(){
                this.age = 20;
            }
        }
    	总之,final修饰的成员变量,必须在创建对象之前有值
    
    

第二章 static关键字

2.1 概述
static什么意思: 静态关键字
static也是一个修饰符,用于修饰类中成员变量/成员方法,static修饰的成员我们称之为静态成员/类成员
    
"被static修饰的成员,不属于任何一个对象,属于整个类,被所有对象共享"    

2.2 定义和使用格式
  • 类变量

    类变量:就是使用static修饰的成员变量,我们称为类变量/静态变量
        "被static修饰的成员变量,不属于任何一个对象,属于整个类,被所有对象共享" 
    /**
     * 学生类
     */
    public class Student {
        int age;
        String name;
        //静态变量,类变量,在内存的方法区中的静态区,只有一份(所有对象共享它)
        static String school = "黑马程序员";
    
    
        public void show(){
            System.out.println("姓名:"+name+",年龄:"+age+",学校:"+school);
        }
    }
       
    
    public class TestStudent {
        public static void main(String[] args) {
            //1.第一个学生
            Student s1 = new Student();
            s1.name = "孙嘉华";
            s1.age = 18;
    
            s1.show();
    
            System.out.println("============");
            //2.第二个学生
            Student s2 = new Student();
            s2.name = "赵广顺";
            s2.age = 35;
    
            s2.show();
    
            System.out.println("=============");
            //孙嘉华同学去了"传智专修学院"
            //修改了静态区中的共享变量,所有对象访问时,都能看到修改后的结果
            s1.school = "传智专修学院";
    
            System.out.println("=============");
    
            s1.show();
            s2.show();
    
        }
    } 
    
    

    在这里插入图片描述

  • 静态方法

    静态方法也叫类方法,static修饰的方法
    特点: 正常的方法必须通过对象才能调用,静态方法不需要通过对象,通过类名就可以直接调用
     
    /**
     * 计算器类
     */
    public class Calculator {
    
        //计算两个数的和
        //这就是静态方法/类方法
        public static int getSum(int a, int b) {
            return a + b;
        }
    }
    public class TestCalculator {
        public static void main(String[] args) {
            //1.创建对象
    //        Calculator cc = new Calculator();
    //        int sum = cc.getSum(111, 999);
    //        System.out.println("求和为:"+sum);
            //2.静态方法,直接通过类名调用即可
            int sum = Calculator.getSum(111, 999);
            System.out.println("求和为:"+sum);
        }
    }    
    
    
2.3 静态和非静态之间的相互调用
静态成员变量
静态成员方法
    与类是同级,只要类加载到内存,静态的成员变量/成员方法就存在(对象不一定存在)
    
非静态成员变量    
非静态成员方法
    必须创建对象之后才能访问/调用
    
生命周期看:
	静态出现的比非静态要早!!!!
 
 结论:
	a.静态与静态之间,非静态与非静态之间是可以相互访问的
    b.非静态可以访问静态,但是静态不能访问非静态       
    静态的: 秦始皇(出现早)
    非静态: 我们(出现晚)    

2.4 建议调用格式
静态的成员变量
    对象名.静态的成员变量 【可以访问的,但是我们不建议】
    类名.静态的成员变量 【建议访问的方式】
    
静态的成员方法    
    对象名.静态的成员方法() 【可以访问的,但是我们不建议】
    类名.静态的成员方法() 【建议访问的方式】
总结: 静态成员虽然可以通过对象名去访问/调用,但是我们更建议直接使用类名去访问/调用    

第三章 接口【重要】

3.1 概述
什么是接口:
	也是一种引用类型,接口是方法的集合(接口中主要写方法)       

3.2 定义格式
定义类: class
定义接口: interface   
定义枚举: enum 【以后讲解】
定义注解: @interface 【以后讲解】
    
格式:
	public interface 接口名{
          //抽象方法【JDK7】
          //默认方法和静态方法【JDK8】
          //私有方法和私有静态方法【JDK9了解】 	
    }

/**
 * 定义接口的格式
 */
public interface MyInterface {
    //抽象方法【主要】,只有接口中抽象方法 public abstract 关键字可以省略(省略不代表没有,编译器会自动添加)
    public abstract void abs1();
    public abstract void abs2();
    //默认方法
    //使用一个关键字修饰 default
    public default void m1(){
        System.out.println("接口中的默认方法1");
    }
    public default void m2(){
        System.out.println("接口中的默认方法2");
    }
    //静态方法
    //使用一个关键字 static
    public static void s1(){
        System.out.println("接口中的静态方法1");
    }
    public static void s2(){
        System.out.println("接口中的静态方法2");
    }
}

3.3 接口的使用
a.和抽象类类似,接口也是不能创建的对象的
b.接口也是作为父接口使用的,用于被其他类"实现"的 
c.继承使用extends关键字,实现使用"implements"关键字
    
使用方式:
	public class 实现类 implements 接口名{
        //a.必须重写接口中所有的抽象方法
        //b.选择性重写接口中的默认方法,但是重写后不能有default
        //c.静态方法没有重写的说法,因为它是通过所在类/接口的名字直接调用的
    }

/**
 * 实现类
 */
public class MyClass implements MyInterface {
    //a.实现类 必须 重写接口中的所有抽象方法
    @Override
    public void abs1() {
        System.out.println("重写后的abs1...");
    }

    @Override
    public void abs2() {
        System.out.println("重写后的abs2...");
    }
    //b.实现类 可以 选择性重写默认方法,但是重写后不能加default
    @Override
    public void m1() {
        System.out.println("重写后的m1方法..");
    }
    //c.静态方法通过类名/接口名 直接调用的,没有重写这种说法
    public static void s1(){
        System.out.println("实现类中的静态方法1");
    }
}

测试类
public class TestDemo {
    public static void main(String[] args) {
        //1.创建实现类对象
        MyClass mc = new MyClass();
        //2.抽象方法
        mc.abs1();
        mc.abs2();
        //3.默认方法
        mc.m1(); //调用实现类的重写方法
        mc.m2(); //调用接口中的默认方法
        //4.静态方法
        MyInterface.s1(); // 接口的s1
        MyClass.s1(); // 实现类的s1
    }
}    

3.4 接口的多实现
格式:
	public class 实现类 implements 接口1,接口2,..{
        //a.实现类需要重写所有接口中的所有抽象方法
    		//如果有抽象方法是一样的,那么实现类只需要重写一次
        //b.实现类可以选择性重写所有接口中的默认方法
    		//如果接口中有一样的默认方法,实现类必须重写一次
        //c.静态方法没有重写的概念,就算多个接口中有一样的静态方法
    		//也不冲突,通过各位所在的接口名调用,没有歧义
    }

/**
 * 实现类:多实现
 */
public class MyClass implements MyInter1,MyInter2{
    //1.抽象方法
    //实现类必须重写所有接口中的所有抽象方法
    //如果有抽象方法是一样的,那么实现类只需要重写一次
    @Override
    public void abs1() {
        System.out.println("实现类重写后的抽象方法1..");
    }

    @Override
    public void abs2() {
        System.out.println("实现类重写后的抽象方法2...");
    }
    //abs方法
    @Override
    public void abs() {
        System.out.println("实现类重写后的抽象方法s");
    }
    //2.默认方法
    //实现类可以选择性重写所有接口中的默认方法
    //如果接口中有一样的默认方法,实现类必须重写一次
    @Override
    public void show() {
        System.out.println("实现类重写后的默认方法show...");
    }
    //3.静态方法
    //静态方法没有重写的概念,就算多个接口中有一样的静态方法
    //也不冲突,通过各位所在的接口名调用,没有歧义
    //通过MyInter1.s()和通过MyInter2.s()
    public static void s(){
        System.out.println("实现类自己的s方法");
    }
}

public class TestDemo {
    public static void main(String[] args) {
        //创建实现类对象
        MyClass mc = new MyClass();
        //1.抽象方法
        mc.abs1();
        mc.abs2();
        mc.abs();
        //2.默认方法
        mc.show1(); //调用接口1的默认方法show1
        mc.show2(); //调用接口2的默认方法show2
        mc.show(); //调用实现类重写后的show
        //3.静态方法
        MyInter1.s();
        MyInter2.s();
        MyClass.s();
    }
}


3.5 实现和继承的优先级问题
一个类 可以在继承一个父类的同时实现多个接口(继承和实现可以同时存在)
格式:
	public class 子类/实现类 extends 父类 implements 接口,...{
        
    }
继承的优先级 高于 实现,所以必须先extendsimplements
 
public interface MyInter {
    //默认方法
    public default void show(){
        System.out.println("接口的默认方法");
    }
}

public class Fu {
    //正常方法
    public void show(){
        System.out.println("父类的show方法");
    }
}

public class Zi extends Fu implements MyInter{
    //如果父类中的正常方法和接口中的默认方法一样了
    //a.那么子类需要不需要对同名的show方法进行重写呢??
    	//子类可以不重写该方法,调用优先调用父类中的show
    //b.那么子类能不能重写show方法呢???
    	//可以重写,重写后,优先调用子类重写后的方法
    @Override
    public void show() {
        System.out.println("子类重写后的show...");
    }
}

public class TestDemo {
    public static void main(String[] args) {
        //1.创建子类对象
        Zi zz = new Zi();
        zz.show();
    }
}

3.6 接口的多继承【了解】
类和类之间: 单继承
类和接口之间: 多实现
接口和接口之间: 多继承
格式:    
    public interface MyInter extends Inter1,Inter2{
        MyInter接口包含Inter1和Inter2接口所有东西
    }
接口多继承我们只做了解即可,我们在开会中很少写这种代码   
    public class MyClass implements MyInter{
        
    }public class MyClass implements Inter1,Inter2{
        
    } 
	效果是一样

3.7 接口中其他成员特点
a.接口中,无法定义成员变量,但是可以定义常量(字面值常量,public static fina修饰的常量)
    	其值不可以改变,默认使用public static final修饰(可省略,但是编译器会自动添加)
    【public static final】 数据类型 常量名 =; 【常量名一般纯大写,多个单词之间使用_分隔】
b.接口中,没有构造方法,不能创建对象。      
c.接口中,没有静态代码块【明后天讲解】          

3.8 抽象类和接口的练习
案例介绍:

在这里插入图片描述

代码实现
/**
 * 狗类,所有狗的共性内容
 */
public class Dog {
    int age;
    String name;

    public void bark(){
        System.out.println("小狗汪汪~~~");
    }

    public void run(){
        System.out.println("小狗旺旺~~~");
    }
}

/**
 * 缉毒接口,其中包含缉毒抽象方法
 */
public interface JiDu {
    //缉毒抽象方法
    public abstract void jiDu();
}

/**
 * 超级狗(缉毒狗)
 */
public class SuperDog extends Dog implements JiDu{
    //必须重写接口的缉毒方法
    @Override
    public void jiDu() {
        System.out.println("旺旺,站住,别跑,否则老子开抢了...");
    }
}

public class TestDemo {
    public static void main(String[] args) {
        //1.创建一个缉毒狗
        SuperDog superDog = new SuperDog();
        //2.调用方法
        superDog.bark();
        superDog.run();
        superDog.jiDu();
    }
}

总结

描述final
    修饰类: 该类不能被继承
    修饰方法: 该方法不能被重写
    修饰变量: 该变量只能赋值一次
        局部变量: 可以在定义时赋值,可以先定义后赋值
		成员变量: 可以在定义时赋值,可以在构造方法中赋值
		引用类型变量: 表示该引用类型变量的地址值不能改变,但是地址内成员变量的值是可以改变
能够掌握static关键字修饰的变量调用方式
         类名.成员变量名【建议的使用方式】   
能够掌握static关键字修饰的方法调用方式
         类名。成员方法名() 【建议的使用方式】   
            
能够写出接口的定义格式
        public interface 接口名{
            //抽象方法【我们最最最常写】
            //默认方法
            //静态方法
        }
能够写出接口的实现格式
    	public class 实现类 implements 接口名,...{
             //a.重写所有抽象方法,如果有相同只需要重写一次
             //b.选择性重写默认方法,如果相同必须重写一次
             //c.静态方法没有重写的概念
        }
能够说出接口中的其他成员特点
    a.没有成员变量,只有常量
    		[public static final] 数据类型 常量名 =;
	b.没有构造方法,也不能创建对象
    c.也没有静态代码块[明后天搞定!]    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值