博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java 抽象方法、final与static、代码块和内部类
阅读量:3926 次
发布时间:2019-05-23

本文共 4836 字,大约阅读时间需要 16 分钟。

一、抽象类与抽象方法

1、什么是抽象类?

      抽象类是用来捕捉子类的通用特性的使用 abstract 关键字修饰的类。一般的,抽象类命名,以Abstract作为前缀,见名知义

特点:

     1)不能创建实例即不能new一个抽象类(对象调用抽象方法,无方法体,没有意义)。

     2)抽象类可以不包含抽象方法,若一旦包含,该类必须作为抽象类。

     3)若子类没有实现父类所有的抽象方法,那么子类也得作为抽象类(抽象派生类)。

     4)构造方法不能都定义成私有的,否则不能有子类(创建子类对象前先调用父类构造方法)。

     5)抽象类不能使用 final 修饰,因为必须有子类,抽象方法才能得以实现。

     6)是不完整的类,需作为基类,功能需要子类来实现。  

2、抽象方法

     使用 abstract 修饰且没有方法体的方法,称为抽象方法。

特点:

     1)使用抽象abstract修饰,方法没有方法体,留给子类去实现。

     2)抽象方法修饰符不能是 private final 以及 static(继承/实现,方法覆盖才有意义)

     3)抽象方法必须定义在抽象类或接口中。

    抽象方法要求子类必须重新覆盖,若子类不覆盖,则子类也声明为抽象类。

3、抽象类和普通类的区别

     1)抽象类,也是一个类,可以定义抽象方法(没有方法体的方法).

     2)抽象类不能创建对象.

     除此之外,其他都一样。

abstract public class Human {    protected String name = "Human";    abstract public void study();}public class Student extends Human{    @Override    public void study() {        System.out.println("Student study...");    }    public static void main(String[] args) {        Human human = new Student();        human.study(); //Student study...        System.out.println(human.name);//Human.    }}

二、final 与 static 修饰符

1、final 修饰符

     可以修饰类、方法和变量。

1)final 修饰的类为最终类,该类不能有子类。

    只要满足以下条件就可以把一个类设计成final类:

      (1)某类不是专门为继承而设计。

      (2)出于安全考虑,类的实现细节不许改动。

      (3)确信该类不会再被拓展。

   比如:java中八大基本数据类型的包装类和String类等,是用 final 修饰的final类.

2)final 修饰的方法为最终方法,该方法不能被子类所覆盖.

    什么时候把方法设计为final的呢?

      (1)父类在构造器中调用的初始化方法.

      (2)父类中提供好的算法业务操作,只应该让子类调用,不能被子类继承.

3)final 修饰的变量为常量,只能赋值一次,值不能再改变。

     final是所有修饰符中唯一一个可以修饰局部变量的修饰符。

     常量的起名规则:全部由大写字母组成,若干个单词之间用下划线分割,比如:MAX_VALURE。MIN_VALUE.

final修饰基本类型常量:

        final int age = 17;//age变量只能被赋值一次.

final修饰引用类型常量:

        final User user = new User();

        user 所引用堆空间的内存地址值不能改变,引用地址中的内容可以改变。

2、static 修饰符

     static 可以修饰成员变量、方法和内部类,它修饰的东西被所有对象所共享,依赖于类,随着类的加载而加载,可通过类名直接调用访问。

类成员(static修饰成员)的特点:

    1)随着类被加载进JVM时,同时对类成员初始化并在内存中分配空间。

    2)优先于对象存在.(对象是通过new出来的.)

    3)被该类的所有对象所共享.

    4)直接使用类名调用即可.

static 不能与 this super 一起使用:

     static优先于对象存在,static是在加载进JVM就存在了,而this与super是new出来的属于对象.

public class Human {    private String name = "Human";    public String getName() {        return name;    }}public class Student {    private final String STUDENT_NUMBER = "NO."+ System.currentTimeMillis();    private static final Human HUMAN = new Human();    public final void study() {        System.out.println("Student study...");    }    public static void main(String[] args) {        Student student = new Student();        student.study(); // Student study...        System.out.println(student.getSTUDENT_NUMBER()); // NO.1563025279841        // HUMAN = new Human(); // 再赋值会报错        System.out.println(HUMAN.getName()); // Human    }    public String getSTUDENT_NUMBER() {        return STUDENT_NUMBER;    }}

三、代码块

     代码块:在程序中类/方法中,使用 {} 括起来的一段代码。在代码块中定义的变量的的作用范围,只在该代码块内有效.

而根据代码块存在的位置与修饰符的不同可分为三类:

1、局部代码块:

       在方法中定义的代码块,比如 if{},while,for等语句.

2、初始化代码块(构造代码块):

       在类中直接定义,与方法是平行关系,用来做初始化操作。

       在创建包含初始化代码块所在类的对象时, 优先于构造器执行,创建N个对象,则执行N次。              

       开发中,不推荐使用,即使要在创建对象的时候做初始化操作,我们一般在构造器中完成即可.

3、静态代码块:

        使用 static 修饰的初始化代码块.

        当静态代码块所在类的字节码被加载进JVM时,就立马执行静态代码块,而且只会执行一次

        一般的,做静态资源的初始化,加载文件,加载资源.

        静态代码块优先于 main 方法执行(main方法,是在字节码被加载进JVM之后,再调用的)。

 

成员属性的初始化顺序:

     先静态后非静态

     先声明后赋值

     先字段后构造方法

     先父类后子类

public class Student {    public Student() {        System.out.println("构造器。。。");    }    {        System.out.println("初始化代码块。。。");    }    static {        System.out.println("静态代码块。。。");    }    public static void main(String[] args) {        System.out.println("main 方法。。。");        new Student();        new Student();        new Student();    }}

     

四、内部类

      内部类可以看做是外部类的一个成员,那么内部类可以使用 public/缺省/protected/private 修饰,还可以是static修饰。

1、为什么使用内部类:

     1)增强封装,把内部类隐藏在外部类之内,不许其他类访问内部类。

     2)内部类能提高代码的可读性和可维护性,把小型类嵌入到外部类中结构上代码更靠近。

     3)内部类可以直接访问外部类的成员。

一般在开发中什么时候使用内部类.

    1)这个类只需要让当前的外部类访问.

    2)匿名内部类.

2、内部类根据使用的修饰符不同或者位置不同,可分为四种:

         

     对于每个内部类来说,Java 编译器会生成独立的 .class 文件

1)非静态内部类/实例内部类:外部类名$内部类名.class

       没有使用static修饰,说明非静态内部类属于外部类的对象,不属于外部类本身。 

特点:

(1)创建实例内部类前,必须存在外部类对象,通过外部类对象创建内部类对象(当存在内部类对象时,一定存在外部类对象).

          Outter.Inner in = new Outter().new Inner();

(2)实例内部类的实例自动持有外部类的实例的引用,内部类可以直接访问外部类成员(看反编译).

(3)外部类中不能直接访问内部类的成员,必须通过内部类的实例去访问.

(4)实例内部类中不能定义静态成员,只能定义实例成员.

(5)如果实例内部类和外部类存在同名的字段或方法xxx时,那么

       在内部类中使用 this.xxx  表示访问内部类成员.

       在内部类中使用 外部类对象.xxx  表示外部类成员.

       在外部类中使用 this.xxx  表示访问外部类成员.

2)静态内部类:  外部类名$内部类名.class

       内部类使用static修饰。

特点:

(1)静态内部类的实例不会自动持有外部类的特定实例的引用,在创建内部类的实例时,不必创建外部类的实例.

     Outter.Inner in = new Outter.Inner();

(2)静态内部类可以直接访问外部类的静态成员,如果访问外部类的实例成员,必须通过外部类的实例去访问.

(3)在静态内部类中可以定义静态成员和实例成员.

(4)测试类可以通过完整的类名直接访问静态内部类的静态成员.

3)局部内部类(打死都不用,破坏封装):  外部类名$数字内部类名.class

       定义在方法中的内部类,其可见范围是当前方法和局部变量是同一个级别.

       局部内部类只能访问 final 修饰的局部变量

特点:

(1)不能使用 public,private,protected,static修饰符.

(2)局部内部类只能在当前方法中使用.

(3)局部内部类和实例内部类一样,不能包含静态成员.

(4)局部内部类和实例内部类,可以访问外部类的所有成员.

(5)局部内部类访问的局部变量必须使用final修饰(在Java8中是自动隐式加上final,但是依然是常量,不能改变值). 原因:

       如果方法中的局部变量不使用 final 修饰,存在于方法的内存空间中,

       方法调用结束,方法空间就被消化,局部变量也就被销毁了,

       使用 final 修饰的变量,表示常量,存放与常量池,方法销毁之后,该常量依然存在,则对象可以继续访问.

4)匿名内部类(Anonymous):外部类名$数字.class

       匿名内部类是一个没有名称的局部内部类,适合于仅使用一次的类。

特点:

(1)匿名内部类本身没有构造器,但是会调用父类构造器.

(2)匿名类尽管没有构造器,但是可以在匿名类中提供一段实例初始化代码块,JVM在调用父类构造器后,会执行该段代码.

(3)内部类处理可以继承类之外,还可以实现接口.

 

 

转载地址:http://uncgn.baihongyu.com/

你可能感兴趣的文章
xz压缩命令
查看>>
Mysql各种存储引擎对比总结(常用几种)
查看>>
java为我们已经提供了各种锁,为什么还需要分布式锁?
查看>>
一文带你理解mysql中的分区表和合并表(一个常见知识点)
查看>>
为什么 MongoDB 索引选择B-树,而 Mysql 选择B+树(精干总结)
查看>>
你的钱为什么被转走,这篇文章告诉你答案(CSRF详解)
查看>>
JVM中的一个小知识点:深堆和浅堆的概念
查看>>
HashMap的负载因子初始值为什么是0.75?这篇文章以最通俗的方式告诉你答案
查看>>
详解java中一个面试常问的知识点-阻塞队列
查看>>
除了Thread和Runnable,你还知道第三种创建线程的方式Callable吗
查看>>
java线程面试题集锦(第一版本)
查看>>
记一次java中三元表达式的坑(避免踩坑)
查看>>
设计模式之桥接模式
查看>>
设计模式之组合模式
查看>>
java网络编程(1)基础知识点总结
查看>>
java网络编程(2)Socket编程案例(TCP和UDP两种)
查看>>
设计模式之享元模式
查看>>
深入分析java中的多态原理(jvm角度分析)
查看>>
SpringBoot系列(1)基础入门和案例
查看>>
设计模式之命令模式
查看>>