JavaSE 三个修饰符 abstract static final

一、abstract(抽象的)

1、abstract可以用于修饰类

  • 被abstract修饰的类称为抽象类。

语法:abstract class 类名{}

  • 抽象类编译之后会生成独立的 .class 文件
package day28;
class TestAbstract{
   public static void main(String[] args){	
   }
}
//抽象类
abstract class MyClass{}

在这里插入图片描述

  • 抽象类不能单独创建对象(即不能 new 对象),但是可以声明抽象类类型的引用 (简称:可以声明引用)
//MyClass mc = new MyClass();
//报错:MyClass 是抽象的; 无法对其进行实例化 
		MyClass mc;
  • 抽象中可以定义 成员变量 和 成员方法
  • 抽象类中有构造方法,但是抽象类中构造方法不再是用于new 对象,而是供子类创建对象时,JVM默认创建一个父类对象时应用。

2、abstract可以用于修饰方法

  • 被 abstract 修饰的方法称为抽象方法
  • 抽象方法不能有主体,只有声明部分,没有方法实现部分(连 {}都没有),以分号结尾

语法: 访问修饰符 abstract 返回值类型 方法名(形参列表);
例子:
public abstract void m2();
abstract public void m3();
注意:访问修饰符 和 abstract 没有先后位置。

  • 抽象方法只能定义在抽象类中;但是抽象类中既可以定义抽象方法,也可以定义非抽象方法。

3、抽象的子类

  • 如果一个类继承抽象类,此类为抽象类的子类
  • 如果子类不想定义为抽象类,必须覆盖父类中所有的抽象方法,否则子类必须定义抽象类。
  • 抽象类类名 引用名 = new 子类类名(形参);
  • 抽象类强制使用多态。
class TestAbstract{
	public static void main(String[] args){	
		//MyClass mc = new MyClass();//报错:MyClass 是抽象的;无法对其进行实例化
		//MyClass mc;
		//mc = new Sub2();//强制使用多态
		MyClass mc = new Sub2();
		mc.m1();
		mc.m2();
		mc.m3();
	}
}
//抽象类
abstract class MyClass{
	int a;//可以定义属性
	public void m1(){
		System.out.println("m1()实现...");
	}//可以定义成员方法
	
	public abstract void m2();//抽象方法不能有主体,没有{},有;
	abstract public void m3();
	
}
abstract class Sub1 extends MyClass{}
class Sub2 extends MyClass{
	 public void m2(){
		 System.out.println("m2()实现...");
	 }
	 public void m3(){
		 System.out.println("m3()实现......");
	 }
 }
  • 抽象类强制使用多态。
  • 抽象类的应用场景:
    1、通常将一些父类定义为抽象类:具有某一类事物的特性和行为,但是不具有具体的执行功能(实现)。例如:动物类、图形类等。
    2、**依赖倒转原则:**当一个类和另外一个类建立关联时,尽可能避开直接和子类建立关系,而是与其父类建立联系。
    a. 降低程序之间的耦合度,从而实现弱耦合。
    b. 提高代码的可维护性
    在这里插入图片描述
    在这里插入图片描述

abstract:能修饰类和方法

二、static(静态的)

1、static可以修饰属性

  • 被static修饰的属性称为静态属性,静态变量,类变量

语法:访问修饰符 static 数据变量 变量名;
访问修饰符 static 数据变量 变量名 = 值;
注意:访问修饰符 和 static 没有位置先后。

  • 特点:静态变量/静态属性/类变量 是依赖于类的变量,和创建多少对象没有关系,被每一个对象共享
    注意:实例变量(非静态变量)每一个对象独有一份
    静态变量让每一个对象共享。

  • 使用:
    a.引用名.静态属性名
    b.类名.静态属性名

  • 内存分析如下:
    在这里插入图片描述

  • 案例:

class TestMyClass{
	public static void main(String[] args){
		MyClass mc1 = new MyClass();
		MyClass mc2 = new MyClass();
		mc1.value = 20;
		mc1.m =3;
		System.out.println("mc1.value = "+mc1.value);//20
		System.out.println("mc1.m = "+mc1.m);//3
		System.out.println("mc2.value = "+mc2.value);//10
		System.out.println("mc2.m = "+mc2.m);//3
		MyClass mc3 = new MyClass();
		System.out.println("mc3.m = "+mc3.m);//3
		mc3.m=100;
		System.out.println("mc3.m = "+mc3.m);//100
		System.out.println("mc2.m = "+mc2.m);//100
		System.out.println(MyClass.m);
		MyClass.m = 20;
		MyClass mc = new MyClass();
		System.out.println(mc.m);//20
		MyClass.m = 30;
		System.out.println(mc.m);//30
	}
}
class MyClass{
	int value = 10;
	static int m;//静态属性,静态变量,类变量
	static int n;
}

2、static可以修饰成员方法

  • 被static修饰的方法称为静态方法

语法:
访问修饰符 static 返回值类型 方法名(形参列表){}
注意:访问修饰符 和 static 没有位置上的先后顺序。

  • 使用:
    a.类名.静态方法名(实参)
    b.对象名.静态方法名(实参)

  • 注意
    a.静态方法中不能直接访问本类的非静态成员(实例变量+成员方法)
    b.静态方法中可以直接访问本类的静态成员(静态变量+静态方法)
    c.非静态方法中既可以直接访问 本类非静态的成员,也可以直接访问本类的静态成员。
    d. 静态方法中不能使用 this 和 super 关键字
    e.父类中的静态方法可以被子类继承
    语法:子类类名.父类静态方法名(实参);
    f. 如果子类覆盖父类中的静态方法,则子类覆盖的方法也必须是静态的(静态方法只能被静态方法覆盖);以父类型的引用调用静态方法,直接访问父类中静态方法,没有体现多态的覆盖结果。

  • 应用场景:为了方便调用,通常将工具类中方法定义为静态方法。

例如:java.util.Arrays.sort(数组名);
java.util:包名
Array:类名
sort:方法名

System.out.println();实现原理
System:类名(位于java.util中的);
out:System类中被static修饰的静态属性,引用;
println:out数据类型中方法。

3、static可以修饰初始代码块

  • 初始化代码:也称为动态代码块
    (1) 定义在 类以内,方法以外的 {}
    (2) 作用:创建对象时,按照和属性(实例变量)定义的先后顺序完成对属性初始化工作。
  • 静态初始化代码块(重点)
    (1) 定义在类以内,方法以外,被 static 修饰的 {}
    static{}
    (2) 作用:在类加载的时候,按照静态属性定义的先后顺序完成静态属性的初始化工作。
    (3) 类加载
    ① 类加载:JVM第一次使用一个类的时候,通过classPath(类路径)找到所需要的类对应的 .class 文件,读取并获取类对应信息(包名、类名、属性、构造方法、成员方法、父类等信息),将类的信息保存到JVM内存中,一个类类加载进行一次。
    第一次使用一个类:
    a. 第一次调用类中静态成员(静态属性和静态方法)
    b. 第一次创建一个类的对象:先进行类加载,再完成对象的创建
    c. 子类类加载会先导致其父类进行类加载
    **注意:**只是声明引用,不会导致类加载(MyClass mc;)
class Test3{
	public static void main(String[] args){
		Sub sub = new Sub();//142356
		/*
			先类加载:(静态初始化)static{}
				加载父类  --1
				加载子类 --4
			创建对象:
				new : 分配空间
				执行子类构造方法
					super()--》执行父类构造方法
						(1)初始化内容(属性初始化语句+初始代码块/动态代码块) --2
						(2)执行父类构造方法中其它语句  --3
					继续执行子类构造方法中其它内容:
						(1)属性初始化内容(属性初始化语句+初始代码块/动态代码块)--5
						(2)执行子类构造方法中其它语句  --6	
		*/
		
		//System.out.println(Sub.n);//149(这是第一句时)
	}
}
class MyClass{
	static int m = 8;
	static{
		System.out.println("父类静态类加载...");//1
	}
	{
		System.out.println("父类动态类加载...");//2
	}
	public MyClass(){
		System.out.println("父类构造方法加载...");//3
	}
}
class Sub extends MyClass{
	static int n = 9;
	static{
		System.out.println("子类静态类加载...");//4
	}
	{
		System.out.println("子类动态类加载...");//5
	}
	public Sub(){
		System.out.println("子类构造方法加载...");//6
	}
}

三、final(最终的、最后的)

int a;//实例变量
static int b;//静态变量、静态属性、类变量
这些都是成员变量

1、final可以修饰变量(局部变量,实例变量,静态变量)

  • final修饰的变量是作用范围内的常量,只允许一次赋值,不允许更改
    注意:final修饰的变量通常以全大写字母作为名字

  • final 修饰 实例变量,JVM不再分配默认值
    final修饰 实例变量 的位置:
    a.在声明的同时 初始化;
    b.可以在构造方法中对其初始化,但是必须保证每一个构造方法中都有对其初始化的语句。

  • final 修饰 静态变量,JVM不再分配默认值
    final修饰 静态变量 的位置:
    a.在声明的同时 初始化;
    b.可以在静态代码块中完成对其初始化

  • 如果引用被final修饰,代表引用中的存储地址不可以改变,但是可以通过引用对象的属性进行修改

font size=4>1、final可以修饰方法

  • 被final修饰的方法被子类继承,但不允许覆盖
    System 、String、Math等一些工具类通常会定义为final类。

总结:
三个修饰符(abstract、static、final)的内容:
abstract:可以修饰类、方法
static:可以修饰属性、方法、静态代码块
final:可以修饰类变量(局部变量,静态变量,实例变量)、方法、、类

abstract、static、final都不能用于修饰构造方法
1.abstract:抽象方法只有方法的声明,没有方法的实现,实现部分让子类完成;但是构造方法是不能被子类继承,如果构造方法被abstract修饰,则子类无法完成构造方法的实现内容。
2.static:static和对象没有关系,但是构造方法是用于创建对象的,相互矛盾;同时static修饰的方法可以直接通过类名.静态方法名(实参);调用,但是构造方法不允许手动调用。
final:final方法是约束子类不能覆盖,但是构造方法本身不允许子类继承。谈不上覆盖,所以没必要用final修饰。

private、abstract、static、final是否能联合修饰成员方法
a.private 和 abstract :private修饰的方法不能被子类继承,abstract修饰的方法需要通过子类覆盖与方法的实现部分,联合修饰一个成员,二者矛盾;
b.static 和 abstract :static方法可以直接通过类名.方法名(实参);进行调用,如果通过类名调用一个抽象方法(半成品),JVM无法执行,二者不能联合修饰一个成员方法;
c.final 和 abstract :final修饰的方法可以被子类继承,但是不允许被覆盖,而abstract修饰的方法的实现需要通过子类覆盖时给与实现,二者不能联合使用。

private、static、final可以联合使用

一个方法中必须而且只能有一个访问修饰符
private、default、protected、public(4个访问修饰符)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值