【JavaSE】一篇文章拿下final关键字和抽象类

文章详细阐述了Java中final关键字的用法,包括final修饰类、方法和变量的规则与限制,并提供了示例代码。同时,介绍了抽象类的概念,强调抽象类用于表示具有不确定方法实现的类,并指出抽象类不能被实例化,但可以包含非抽象方法。文章还讨论了抽象方法的特性,以及继承抽象类时的注意事项。
摘要由CSDN通过智能技术生成

1.1🍒final的定义

final在中文中的意思就是最后的、最终的

final在Java中可以修饰类、属性、方法、局部变量
(1).当不希望一个类被继承时,可以用final修饰
(2).当不希望一个父类的某个方法被子类重写,可以用final使这个方法不能被重写
(3).当不希望某个属性被修改,可以用final修饰
(4).当不希望某个全局变量被修改,可以用final修饰

// >(1).当不希望一个类被继承时,可以用final修饰

final class A{}

//class B extends A{   //err
//}


// >(2).当不希望一个父类的某个方法被子类重写,可以用final使这个方法不能被重写
class C{
    public final void m1(){}
}

class D extends C{
//    @Override
//    public void m1(){}  // err
}


// >(3).当不希望某个属性被修改,可以用final修饰
class E{
    // 无法修改
    public final double TAX_RATE = 0.08;
}

// >(4).当不希望某个全局变量被修改,可以用final修饰

class F{
    public void cry(){
        // 局部常量
        final double NUM = 0.01;
        // NUM = 0.9; // err

    }
}

1.2🍿final细节

1.final所修饰的属性,会被称作常量,命名规范XXX_XXX_XXX_
2.final所修饰的属性必须赋初始值,可以在以下3个方面进行初始化
(1). 定义时:如 public final double TAX_RATE=0.08;
(2). 在构造器中
(3). 在代码块中
3. 如果final修饰的属性是静态的,则初始化的位置只能是
1 定义时 2 在静态代码块 不能在构造器中赋值。
4.final类不能继承,但是可以实例化对象
5.如果类不是final类,但是含有final方法,则该方法虽然不能重写,但是可以被继承
6.一般来说,如果一个类已经是final类了,就没有必要再将方法修饰成final方法
7.包装类,String 是final类,不能被继承
8.final不能修饰构造器
9.final 和 static 往往搭配使用,效率更高,不会导致类加载.底层编译器做了优化处理

class AA {
    /*
    1. 定义时:如 public final double TAX_RATE=0.08;
    2. 在构造器中
    3. 在代码块中
     */
    public final double TAX_RATE = 0.08;//1.定义时赋值
    public final double TAX_RATE2 ;
    public final double TAX_RATE3 ;
    // public final double TAX_RATE4 ;  // final所修饰的变量必须初始化

    public AA() {//构造器中赋值
        TAX_RATE2 = 1.1;
    }
    {//在代码块赋值
        TAX_RATE3 = 8.8;
    }
}
class BB {
    /*
    如果final修饰的属性是静态的,则初始化的位置只能是
    1 定义时  2 在静态代码块 不能在构造器中赋值。
     */
    public static final double TAX_RATE = 99.9;
    public static final double TAX_RATE2 ;

    static {
        TAX_RATE2 = 3.3;
    }
    // err
//    public BB() {
//        TAX_RATE2 = 3.4;
//    }

}

解析
这个好理解,因为是static变量,是在类加载的时候就完成了初始化,再加上final关键字, 必须要创建对象前完成初始化,所以就不能在构造器中进行构造器初始化了

class DD {
    public final void cal() {
        System.out.println("cal()方法");
    }
}
class EE extends DD { }

public class FinalDetail02 {
    public static void main(String[] args) {
        System.out.println(BBB.num);
        //包装类,String 是final类,不能被继承
    }
}

    //final 和 static 往往搭配使用,效率更高,不会导致类加载.底层编译器做了优化处理
    class BBB {
        public final static int num = 10000;

        static {
            System.out.println("BBB 静态代码块被执行");
        }
    }


final class AAA {
    //一般来说,如果一个类已经是final类了,就没有必要再将方法修饰成final方法
    //public final void cry() {}
}

在这里插入图片描述
这里可以看到,一个变量被final和static所修饰时,如果想调用它,不会导致类加载,比如这个静态代码块就没被执行,
从而提升了效率

1.3🍷final练习

说说下面代码哪里错了?

public class FinalExercise02 {
    public int addOne(final int x) { 
    	//错误,原因是不能修改 final x的值
        ++x;  // err 
        //这里是可以.只是返回值并未修改值
        return x + 1; 
    }
}

2.1🍫抽象类的定义

父类方法不确定性的问题 考虑将该方法设计为抽象(abstract)方法

abstract class Animal {
    private String name;

    public Animal(String name) {
        this.name = name;
    }

    //这里eat 这里你实现了,其实没有什么意义
    //即: 父类方法不确定性的问题
    //===> 考虑将该方法设计为抽象(abstract)方法
    //===> 所谓抽象方法就是没有实现的方法
    //===> 所谓没有实现就是指,没有方法体
    //===> 当一个类中存在抽象方法时,需要将该类声明为abstract类
    //===> 一般来说,抽象类会被继承,有其子类来实现抽象方法.
//    public void eat() {
//        System.out.println("这是一个动物,但是不知道吃什么..");
//    }
    public abstract void eat()  ;
}

比如这个eat方法,不知道要实现什么功能,可以用abstract所修饰,这样可以不用写方法体了

2.2🥒抽象类的细节

(1)抽象类,不能被实例化
(2)抽象类不一定要包含abstract方法。也就是说,抽象类可以没有abstract方法
可以有自己的方法。
(3)一旦类包含了abstract方法,则这个类必须声明为abstract
(4)abstract 只能修饰类和方法,不能修饰属性和其它的

public class AbstractDetail01 {
    public static void main(String[] args) {
        //(1)抽象类,不能被实例化
        //new A();
    }
}
//(2)抽象类不一定要包含abstract方法。也就是说,抽象类可以没有abstract方法
//可以有自己的方法。
abstract class A {
    public void hi() {
        System.out.println("hi");
    }
}

//(3)一旦类包含了abstract方法,则这个类必须声明为abstract
abstract class B {
    public abstract void hi();
}
//(4)abstract 只能修饰类和方法,不能修饰属性和其它的
class C {
    // public abstract int n1 = 1;
}

(1)抽象类的本质还是类,所以可以有类的各种成员
(2)如果一个类继承了抽象类,则它必须实现抽象类的所有抽象方法,除非它自己也声明为abstract类
(3)抽象类的方法不能有方法体
(4)抽象方法不能使用private、final 和 static来修饰,因为这些关键字都是和重写相违背的

//(1)抽象类的本质还是类,所以可以有类的各种成员
abstract class D {
    public int n1 = 10;
    public static  String name = "abc";
    public void hi() {
        System.out.println("hi~");
    }
    public abstract void hello();
    public static void ok() {
        System.out.println("ok~");
    }
}
//(2)如果一个类继承了抽象类,则它必须实现抽象类的所有抽象方法,除非它自己也声明为abstract类
abstract class E {
    // (3)抽象类的方法不能有方法体
    public abstract void hi();
}
abstract class F extends E {

}
class G extends E {
//这里相等于G子类实现了父类E的抽象方法,所谓实现方法,就是有方法体
    @Override
    public void hi() { 

    }
}

//(4)抽象方法不能使用private、final 和 static来修饰,因为这些关键字都是和重写相违背的
abstract class H {
    public abstract void hi();//抽象方法
}

解析
(1)如果一个类的方法被private修饰,说明这个方法只能在本类使用,子类就不能重写了
(2)不能用final关键字好理解,因为用了final关键字就不能继承这个类,从而不能重写这个方法了
(3)static修饰的是静态方法,可以直接被调用;而abstract修饰的类中只有方法声明,没有方法实现,不能被直接调用。所以二者冲突,不能共存。
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值