day02【final、static、接口】

第一章 final关键字

final: 不可改变。可以用于修饰类、方法和变量。

  • 类:被修饰的类,不能被继承。
  • 方法:被修饰的方法,不能被重写。
  • 变量:被修饰的变量,就只能赋值一次,不能被重新赋值。
  • 被final修饰的常量名称,一般都有书写规范,所有字母都大写

final关键字的概述和使用

修饰类

修饰符 final class 类名 {
  
}
例如:
public final class FinalClassFu {
}
public class FinalClassZi /*extends FinalClassFu*/ {
    // FinalClassFu类被final修饰了,所以不能被继承
}

修饰方法

修饰符 final 返回值类型 方法名(参数列表){
//方法体
}

public class FinalMethodFu {
    public final void show(){

    }
}
public class FinalMethodZi extends FinalMethodFu {

    /*@Override
    public void show() {

    }*/
    // 无法重写父类中的show方法,因为父类中的show方法被final修饰了
}

修饰变量

局部变量——基本类型
基本类型的局部变量,被final修饰后,只能赋值一次,不能再更改。

public class FinalDemo1 {
    public static void main(String[] args) {
        // 声明变量,使用final修饰
        final int A;
        // 第一次赋值 
        A = 10;
        // 第二次赋值
        A = 20; // 报错,不可重新赋值
    }
}

局部变量——引用类型
引用类型的局部变量,被final修饰后,只能指向一个对象,地址不能再更改。但是不影响对象内部的成员变量值的修改

public class FinalDemo2 {
    public static void main(String[] args) {
        // 创建 User 对象
        final User U = new User();
        
        // 创建 另一个 User对象
        // U = new User(); // 报错,指向了新的对象,地址值改变。

        // 调用setName方法
        U.setName("张三"); // 可以修改
    }
}

成员变量

  • 1.显示初始化;
public class FinalVariable {    final int NUM1 = 10;}
  • 2.构造方法初始化。
public class FinalVariable {
    final int NUM2;
    public FinalVariable(int NUM2){
        this.NUM2 = NUM2;
    }
    public FinalVariable(){
        this.NUM2 = 10;
    }
}

第二章 static关键字

static关键字概述

static是一个静态修饰符关键字,表示静态的意思,可以修饰成员变量和成员方法以及代码块。

static修饰成员变量

static 修饰成员变量时,该变量称为类变量。该类的每个对象都共享同一个类变量的值。任何对象都可以更改该类变量的值,但也可以在不创建该类的对象的情况下对类变量进行操作。
定义格式:

static 数据类型 变量名;

静态成员变量的访问方式:

对象名.静态成员变量名;
类名.静态成员变量名;【推荐】

public class ChinesePeople {
    /**
     * 姓名
     */
    public String name;
    /**
     * 年龄
     */
    public int age;
    /**
     * 国籍
     */
    public static String country ;
}

public class Demo {
    public static void main(String[] args) {
        // 使用类名直接访问country
        ChinesePeople.country = "中国";

        // 创建ChinesePeople类的对象,并给属性赋值
        ChinesePeople p1 = new ChinesePeople();
        p1.name = "张三";
        p1.age = 18;
        // 打印所有属性的值
        System.out.println("姓名是:"+p1.name+",年龄是:"+p1.age+",国籍是:"+p1.country);

        // 创建ChinesePeople类的对象,并给属性赋值
        ChinesePeople p2 = new ChinesePeople();
        p2.name = "李四";
        p2.age = 19;
        // 打印所有属性的值
        System.out.println("姓名是:"+p2.name+",年龄是:"+p2.age+",国籍是:"+p2.country);

        System.out.println(new ChinesePeople().country);

    }
}

在这里插入图片描述

statci修饰成员方法

  • 被static修饰的方法会变成静态方法,也称为类方法,该静态方法可以使用类名直接调用。

定义格式:

修饰符 static 返回值类型 方法名 (参数列表){
// 执行语句
}

访问方式

对象名.方法名(实参);
类名.方法名(实参); 【推荐】

静态方法调用的注意事项:

  • 静态方法中不能出现this关键字
  • 静态方法中只能直接访问静态成员变量和静态成员方法
  • 静态方法中不能直接访问非静态成员变量和非静态成员方法
  • 非静态方法中可以直接访问一切成员变量和成员方法
public class People {

    int age = 10;// 非静态成员变量
    static String country;// 静态成员变量

    /**
     * 静态方法
     */
    public static void method() {
        System.out.println("method方法...");
    }

    public static void method1() {
        int age = 20;
        System.out.println("method1方法..." + age);
        // 下一行代码是错误的,静态方法中不能出现this关键字
        //System.out.println("method1方法..."+this.age);
    }

    public static void method2() {
        // 访问静态方法method3
        method3();
        // 访问非静态方法method4
        // method4();// 错误的,因为静态方法中不能直接访问非静态成员方法
    }

    public static void method3() {
        // 访问静态成员变量
        System.out.println(country);
        // 访问非静态成员变量
        // System.out.println(age);// 错误的,因为静态方法中不能直接访问非静态成员变量
    }

    /**
     * 非静态方法
     */
    public void method4() {
        // 访问静态成员变量
        System.out.println(country);
        // 访问静态成员方法
        method3();

        // 访问非静态成员变量
        System.out.println(age);
        // 访问非静态成员方法
        method5();
    }

    public void method5() {
        System.out.println("method5方法...");
    }
}

public class Demo {
    public static void main(String[] args) {
        People.method();
        // 创建People对象
        People p = new People();
        p.method();
    }
}

static修饰代码块

概述

  • 被static修饰的代码块,就叫做静态代码块

格式

static{ }

  • 位置:类中方法外。
  • 执行:随着类的加载而执行且执行一次,优先于main方法和构造方法的执行。
public class Student {
    static {
        // 静态代码块
        System.out.println("静态代码块执行了...");
    }

    public Student() {
        System.out.println("Student类的空参构造方法执行了...");
    }
}

public class StaticDemo {

    static {
        // 静态代码块
        System.out.println("main方法所在的类中的静态代码块执行了...");
    }

    public static void main(String[] args) {
        System.out.println("main方法中的代码...");
        new Student();
    }
}

以后开发中static的应用

以后的项目中,通常会需要一些“全局变量”或者“全局的工具方法”,这些全局变量和方法,可以单独定义在一个类中,并声明为static(静态)的,可以很方便的通过类名访问

  • 例子
public class Utils {
    public static final double PI = 3.14;
    // 找int数组中的最大值
    public static int getArrayMax(int[] arr){
        int max = arr[0];
        for (int i = 0; i < arr.length; i++) {
            if(arr[i] > max){
                max = arr[i];
            }
        }
        return max;
    }
}

public class Demo {
    public static void main(String[] args) {
        System.out.println("π的值:"+Utils.PI);
        int[] arr = {19,56,34,22,55,88,1};
        int max = Utils.getArrayMax(arr);
        System.out.println(max);
    }
}

第三章 接口

概述: 接口是Java语言中的一种引用类型,是方法的"集合",所以接口的内部主要就是定义方法,包含常量,抽象方法(JDK 7及以前),默认方法和静态方法(JDK 8),私有方法(jdk9)。

接口的定义,它与定义类方式相似,但是使用 interface 关键字。它也会被编译成.class文件,但一定要明确它并不是类,而是另外一种引用数据类型。

public class 类名.java–>.class

public interface 接口名.java–>.class

引用数据类型:数组,类,接口。

接口的使用,它不能创建对象,但是可以被实现(implements ,类似于被继承)。一个实现接口的类(可以看做是接口的子类),需要实现接口中所有的抽象方法,创建该类对象,就可以调用方法了,否则它必须是一个抽象类。
小结

  • 接口是一种引用数据类型,接口中主要用来定义方法
  • 接口中的成员: 常量, 抽象方法,默认方法和静态方法,私有方法
  • 接口的特点:
    • 接口编译之后也会产生class文件
    • 定义接口使用Interface关键字
    • 实现接口使用implements关键字
    • 实现接口的类可以叫做实现类或者子类
    • 实现类是普通类就必须重写接口中的所有抽象方法,如果实现类是抽象类可以不用重写也可以重写接口中的抽象方法

定义格式

格式

public interface 接口名称 {
// 常量
// 抽象方法
// 默认方法
// 静态方法 }

案例

public AInterface {
    //1.公有、静态、常量
    public static final int a = 10;
    int b = 20;//编译后:public static final int b = 20;
    public int c = 30;//编译后:public static final int c = 30;

    //2.公有、抽象方法——用来被子类继承,并强制重写
    public abstract void show();
    void show1();//编译后:public abstract void show1();

    //3.公有、默认方法——有方法体,可以被子类继承,子类可以重写,也可以不重写
    public default void method3(){
    }
    default void method4(){//编译后:public default void d4(){};
    }

    //4.公有、静态方法——有方法体,但不能被子类继承,只属于此接口,只能通过此接口名访问。
    public static void method5(){
        System.out.println("静态方法method5()....");
    }
	// 5.了解jdk9以上接口中可以定义私有的静态方法和私有非静态方法,只能在本接口中调用
    private void method6(){
        System.out.println("私有方法method6()....");
    }
    private static void method7(){
        System.out.println("私有静态方法method7()....");
    }
}

实现接口

类与接口的关系为实现关系,即类实现接口,该类可以称为接口的实现类,也可以称为**接口的子类。**实现的动作类似继承,格式相仿,只是关键字不同,实现使用 implements关键字。
实现格式

  • 类可以实现一个接口,也可以同时实现多个接口。
  • 类实现接口后,必须重写接口中所有的抽象方法,否则该类必须是一个“抽象类”。
public interface IA{
    public void show1();
}
public interface IB{
    public void show2();
}
public class Zi implements IA ,IB{
    public void show1(){
    }
    public void show2(){
    }
}
  • 类可以在“继承一个类”的同时,实现一个、多个接口;
public class Fu{}
public interface IA{}
public interface IB{}
public class Zi extends Fu implements IA,IB{//一定要先继承,后实现
}

多实现时的几种冲突情况

①公有静态常量的冲突

  • 实现类不继承冲突的变量
interface IA{
    public static final int a = 10;
    public static final int b= 20;
}
interface IB{
    public static final int a = 30;
}
class Zi implements IA,IB{
    //只继承了b,没有继承a,因为a冲突了
}

public class Demo {
    public static void main(String[] args) {
        Zi z = new Zi();
     //   System.out.println(z.a);//编译错误
        System.out.println(z.b);
    }
}

②公有抽象方法的冲突

  • 实现类只需要重写一个
interface IA{
    public void show();
}
interface IB{
    public void show();
}
class Zi implements IA,IB{
    @Override
    public void show() {//子类只需要重写一个show()即可
        System.out.println("子类的show()...");
    }
}
public class Demo {
    public static void main(String[] args) {
        Zi z = new Zi();
        z.show();
    }
}

③公有默认方法的冲突

  • 实现类必须重写一次最终版本
interface IA{
    public default void show(){
        System.out.println("IA");
    }
}
interface IB{
    public default void show(){
        System.out.println("IB");
    }
}
class Zi implements IA,IB{
    @Override
    public void show() {//必须重写一次的show()
        System.out.println("Zi的show()....");
    }
}
public class Demo {
    public static void main(String[] args) {
        Zi z = new Zi();
        z.show();
    }
}

④公有静态方法的冲突

  • 静态方法是直接属于接口的,不能被继承,所以不存在冲突
interface IA{
    public static  void show(){
        System.out.println("IA");
    }
}
interface IB{
    public static void show(){
        System.out.println("IB");
    }
}
class Zi implements IA,IB{

}
public class Demo {
    public static void main(String[] args) {
        Zi z = new Zi();
        z.show();//编译错误,show()不能被继承。
    }
}

⑤私有方法的冲突

  • 私有方法只能在本接口中直接使用,不存在冲突

接口和接口的关系

  • 接口可以“继承”自另一个“接口”,而且可以“多继承”。
interface IA{}
interface IB{}
interface IC extends IA,IB{//是“继承”,而且可以“多继承”
}

接口继承接口的冲突情况

  • ①公有静态常量的冲突
interface IA{
    public static final int a = 10;
    public static final int b = 30;
}
interface IB{
    public static final int a = 20;
}
interface IC extends IA,IB{//没有继承a
}
//测试:
main(){
    System.out.println(IC.a);//错误的
}
  • ②公有抽象方法冲突
interace IA{
    public void show();
}
interface IB{
    public void show();
}
interface IC extends IA,IB{//IC只继承了一个show()
}
class Zi implements IC{
    //重写一次show()
    public void show(){
    }
}
  • ③公有默认方法的冲突
interface IA{
    public default void d1(){
    }
}
interface IB{
    public default void d1(){
    }
}
interface IC extends IA,IB{//必须重写一次d1()
    public default  void d1(){
    }
}
  • ④公有静态方法和私有方法

不冲突,因为静态方法是直接属于接口的,只能使用接口直接访问,而私有方法只能在接口中访问,也没有冲突

实现类继承父类又实现接口时的冲突

①公有静态常量的冲突–>没有继承

class Fu{
    public static final int a = 10;
}
interface IA{
    public static final int a = 20;
}
class Zi extends Fu implements IA{//没有继承a变量
}
public class Demo {
    public static void main(String[] args) {
        System.out.println(Zi.a);//编译错误
    }
}

② 公有抽象方法的冲突—>重写

class Fu{
    public void show(){
        System.out.println(“a”);
    }
}
interface IA{
    public void show();
}
class Zi extends Fu implements IA{
    //不用必须重写show(),因为从父类继承的show()就可以作为“重写”的。
}
//测试:
main(){
    Zi z = new Zi();
    z.show();//a
}

③公有默认方法的冲突—>优先父类

class Fu{
    public void show(){
        System.out.println("a");
    }
}
interface IA{
    public default void show(){
        System.out.println("b");
    }
}
class Zi extends Fu implements IA{
}
//测试:
main(){
    Zi z = new Zi();
    z.show();//a
}

④公有静态方法---->优先父类

class Fu{
    public static void show(){
        System.out.println("fu...");
    }
}
interface IA{
    public static void show(){
        System.out.println("IA...");
    }
}
class Zi extends Fu implements IA{//只继承了"父类"的静态方法,没有继承接口的静态方法

}
public class Demo {
    public static void main(String[] args) {
        Zi.show();//fu…
    }
}

⑤父类和接口的私有方法

不存在冲突

抽象类和接口的练习

  • 需求:

通过实例进行分析和代码演示抽象类和接口的用法。

1、举例:

​ 犬: 父类

​ 行为:吼叫;吃饭; ----> 将这2个行为用抽象方法来表示

​ 缉毒犬: 继承犬 实现缉毒接口

​ 行为:吼叫;吃饭;缉毒;

  • 分析:

​ 由于犬分为很多种类,他们吼叫和吃饭的方式不一样,在描述的时候不能具体化,也就是吼叫和吃饭的行为不能明确。当描述行为时,行为的具体动作不能明确,这时,可以将这个行为写为抽象行为,那么这个类也就是抽象类。

​ 可是有的犬还有其他额外功能,而这个功能并不在这个事物的体系中 , 例如 : 缉毒犬。缉毒的这个功能有好多种动物都有 , 例如 : 缉毒猪 , 缉毒鼠。我们可以将这个额外功能定义接口中 ,让缉毒犬继承犬且实现缉毒接口 , 这样缉毒犬既具备犬科自身特点也有缉毒功能。

  • 额外的功能—> 在接口中定义,让实现类实现
    共性的功能—> 在父类中定义,让子类继承

实现:

//定义缉毒接口 缉毒的词组(anti-Narcotics)比较长,在此使用拼音替代
interface JiDu{
    //缉毒
	public abstract void jiDu();
}
//定义犬科,存放共性功能
abstract class Dog{
    //吃饭
	public abstract void eat();
    //吼叫
	public abstract void roar();
}
//缉毒犬属于犬科一种,让其继承犬科,获取的犬科的特性,
//由于缉毒犬具有缉毒功能,那么它只要实现缉毒接口即可,这样即保证缉毒犬具备犬科的特性,也拥有了缉毒的功能
class JiDuQuan extends Dog implements JiDu{
	public void jiDu() {
	}
	void eat() {
	}
	void roar() {
	}
}

//缉毒猪
class JiDuZhu implements JiDu{
	public void jiDu() {
	}
}

小结:

  • 额外的功能—> 在接口中定义,让实现类实现
    • 如果可以确定的通用功能,使用默认方法
    • 如果不能确定的功能,使用抽象方法
  • 共性的功能—> 在父类中定义,让子类继承
    • 如果可以确定的通用功能,使用默认方法
    • 如果不能确定的功能,使用抽象方法
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值