三大修饰符:static、abstract、final

发布于:2023-01-08 ⋅ 阅读:(90) ⋅ 点赞:(0)

抽象

抽象类概述: 不能具体化对象的类,叫做抽象类   例如:动物类--拿不出动物的对象(只能找到子类的对象)
抽象方法概述:在抽象类中,有一些方法,不知道如何实现,这样的方法,叫做抽象方法
例如:动物类中有叫的方法,但不知道如何描述---抽象方法
类抽象作用:自身限制了具体化,只能实例化子类对象---更自然使用多态
抽象方法作用:作为模板使用,意味着子类必须重写该方法

抽象类:主要用在多态中,是前面多态的优化
用法:1.直接赋值多态     2.参数多态   3.返回值多态

抽象类的特点:

1、抽象类不能实例化对象

2、抽象类可以有构造方法

3、抽象类中也可以没有抽象方法(一般不会这么做)

4、抽象类中可以有非抽象的方法

5、抽象方法不能出现在普通类中

6、子类不一定必须要重写抽象类的抽象方法,可以把自身变为抽象类

7.抽象类中不一定有抽象方法,但有抽象方法的类一定是抽象类

抽象类的作用:

1、可以被子类继承,提供共性属性和方法

2、可以声明为应用,更自然的使用多态

 抽象类直接多态:

abstract class Animal{ //抽象类
	
	public Animal() {  //有构造方法  通过默认的super()调的
	}
	
	//抽象方法   不能具体实现的方法,但必须要有---模板
	public abstract void bark();  
	
	public void test() {
		
	}
}

如果抽象类的方法是抽象方法,子类必须要进行处理:
1.把自身变为抽象类
2.子类必须实现抽象类的重写方法

/*abstract*/ class Dog extends Animal{

	@Override
	public void bark() {
		System.out.println("旺财在叫");
	}
	
}
public class Abstract1 {
	public static void main(String[] args) {
		//Animal animal = new Animal();  //抽象类不能具体化
		Animal animal = new Dog();  //直接赋值多态
		animal.bark();
	}
}

抽象类参数多态:

//案例:老师开着法拉利牌的交通工具上班,自行车,汽车,飞机等都是交通工具
//分析:类:老师,交通工具(父类)  飞机,自行车,汽车(子类)   行为:开, 运行
abstract class Utils{  //抽象类
	public abstract void run();  //抽象方法---模板
}
class Bike extends Utils{
	@Override
	public void run() {
		System.out.println("自行车在运行");
	}
}
class Car extends Utils{
	@Override
	public void run() {
		System.out.println("汽车在运行");
	}
}
class Teacher{
	public void start(Utils utils) {//实参传子类对象
		utils.run();  //调用子类重写方法
	}
}
public class Abstract2 {
	public static void main(String[] args) {
		Teacher teacher = new Teacher();
		teacher.start(new Bike());  //老师开自行车
		teacher.start(new Car());   //老师开汽车
	}
}

静态

静态(static)可以修饰属性和方法,称为静态属性(类属性)、静态方法(类方法)。

静态成员是全类所有对象共享的成员。

在全类中只有一份,不因创建多个对象而产生多份。

不必创建对象,可以之间通过类名访问。

非静态属性实例化多个对象每个对象都有独立的成员属性

class Girl{
	 String name;
	
	public void wash() {
		System.out.println("女朋友"+name+"在洗衣服");
	}
}
public class Static1 {
	public static void main(String[] args) {
		Girl girl1 = new Girl();
		girl1.name = "小丽";
		
		Girl girl2 = new Girl();
		girl2.name = "翠花";
		
		girl1.wash();  //小丽
		girl2.wash();  //翠花
	}

static+属性==静态属性

java五大存储区域:堆、栈、方法区、本地方法区(例如存放c代码)、寄存器区(与cpu有关)

重点分析堆、栈、方法区。

堆:存new对象,成员属性

栈:存局部变量

方法区:存class 资源 ,静态区,常量池(字符串常量)只有一份共享资源。

静态属性实例化多个对象,每个对象共享同一份静态属性

静态属性与成员属性的区别:
1.存储区域不同   静态属性-方法区  成员属性-堆
2.所属资源不同   静态属性属于类   成员属性属于对象
3.优先级问题:静态属性在类加载是就已经加载了,优先于成员属性
4.调用方式不同   静态属性:类名.属性(推荐)    成员属性:对象.属性

class Girl2{
	 static String name;  //静态属性
	
	public void wash() {
		System.out.println("女朋友"+name+"在洗衣服");
	}
}
public class Static2 {
	public static void main(String[] args) {
		Girl2 girl1 = new Girl2();
		//The static field Girl2.name should be accessed in a static way
		Girl2.name = "小丽"; //静态属性推荐使用:类名.属性
		
		Girl2 girl2 = new Girl2();
		girl2.name = "翠花";
		
		girl1.wash();  //小丽
		girl2.wash();  //翠花
	}
}

静态属性应用场景:

/案例: 统计一个类的对象,被创建了多少次
//分析:通过静态属性来统计次数,实例化多个对象应用共享同一个属性,才能统计次数
//应用场景1:处理共享资源
class A{
	static int count;
	A(){
		count++;
	}
}
public class StaticAttr1 {
	public static void main(String[] args) {
	   new A();
	   new A();
	   new A();
	   System.out.println("共创建了"+A.count+"次对象");
	}
}

//应用场景2:可作为状态值使用(且需要搭配final-最终的)
//案例: 判断男性和女性的状态: 1代表男性  0代表女性
//状态值的好处:可读性更强,可维护性更强
//注意: 往往状态值需要写成: final+static形式--静态常量; 写法:变量全大写,多个单词用_拼接
public class StaticAttr2 {
	static final int SEX_MAN = 1;  //男性
	static final int SEX_WOMAN = 0; //女性
	
	public static void main(String[] args) {
	   int sex = getResult();
	   if(sex==SEX_MAN) { //注意:在当前类中使用静态属性,可省略类名
		   System.out.println("得到结果为男性");
	   }else if(sex==SEX_WOMAN){
		   System.out.println("得到结果为女性");
	   }
	   
	   
	   //SEX_MAN = 0;  //静态常量,值是不能改变的
	   //SEX_WOMAN = 1;
	}

	private static int getResult() {
		return SEX_MAN;
	}
}

静态方法(重点)

静态方法的特点:

1、静态方法允许直接访问静态成员

2、静态方法不能直接访问非静态成员。

3、静态方法中不允许使用this或super关键字

4、静态方法可以继承,不能重写,没有多态

5、静态方法中不能使用成员属性; 在成员方法中可以使用静态属性

class MyArrays{
    int a;  //在静态方法中,不能使用成员属性
    static int b; 
	public static String toString(int[] b) {
		//System.out.println(a);  //加载时机问题,在加载静态资源时,还没有对象,所以不知道对象的属性
		
		//静态方法中,拼接字符串,然后返回
		String s = "[";
		for(int i=0;i<b.length;i++) {
			if(i==b.length-1) { //最后一次,无需加“,”
				s+=b[i]+"]";
			}else {
				s+=b[i]+",";
			}
		}
		return s;
	}
	
	public void test() {
		System.out.println(b);  //在成员方法中可以使用静态属性---加载时机问题
	}
	
}

public class StaticMethod {
	public static void main(String[] args) {
		//前面学过的静态方法调用:
		int[] a = {1,3,5};
		int[] b = Arrays.copyOf(a, a.length+1);
		System.out.println(Arrays.toString(b));
		
		//相比所学的面向对象操作,此处可直接类名调方法,无需实例化对象
		System.out.println(MyArrays.toString(b));
	}
}

动态代码块与类加载

动态代码块:
执行: 实例化对象时,触发执行
执行地位:成员属性->动态代码块->构造方法
作用: 给属性赋值(不常用)

类加载的过程: 
JVM在首次加载类时,通过classpath找到class文件;然后将class文件加载到内存中;
然后可以知道类中的所有信息,包括包名,类名,属性,方法等等信息。

加载时机:创建对象,创建子类对象,访问静态属性,访问静态方法,

主动加载:Class.forName(全限定名)


如何触发加载class:

class A{
	String a = "成员属性";
	//动态代码块
	{
		System.out.println(a);  //成员属性
		System.out.println("动态代码块");
	}
	A(){
		System.out.println("构造方法");
	}
	
	static int b = 4;  //静态属性
	
	//静态方法
	public static void test() {
		System.out.println("静态方法");
	}
	
	
}
class B extends A{
	
}
public class StaticCode1 {
	public static void main(String[] args) throws ClassNotFoundException  {
		//new A();  //实例化自身对象-加载A.class
		//new B();    //实例化子类对象-加载A.class
		//System.out.println(A.b);  //静态属性加载A.class
		//A.test();  //静态方法加载A.class
		Class.forName("com.qf.test4.A");  //通过传入全类名,触发加载A.class(反射对象)
	}
}

静态代码块:动态代码块前+static

执行地位: 静态属性->静态代码块->静态方法
作用:给静态属性进行初始化及触发其他类的加载;例如数据库驱动的加载

静态代码块与动态代码块测试进行结合后,实例化对象的过程---测试:

class C{
	static String s = "静态属性";
	static {
		System.out.println(s);
		System.out.println("静态代码块");
	}
	
	public static void show() {
		System.out.println("静态方法");
	}
}
public class StaticCode2 {
	public static void main(String[] args) {
		C.show();
	}
}

对象的实例化过程:

Super类的实例化过程:

 1.静态属性
 2.静态代码块
 3.成员属性
 4.动态代码块
 5.构造方法
 6.成员属性
 7.动态代码块
  8.Super构造方法
结论: 静态代码块只加载一次;动态代码块,每new一次对象都执行一次

class Super{
	String a = "成员属性";
	{
		System.out.println(a);
		System.out.println("动态代码块");
	}
	
	public Super() {
		System.out.println("Super构造方法");
	}
	
	static String b = "静态属性";
	static {
		System.out.println(b);
		System.out.println("静态代码块");
	}
}
public class StaticCode3 {
	public static void main(String[] args) {
		new Super();
		System.out.println("===========");
		new Super();
	}
}

实例化子类的过程

1.父类的静态属性
 * 2.父类的静态代码块
 * 3.子类的静态属性
 * 4.子类的静态代码块
 * 5.父类成员属性
 * 6.父类动态代码块
 * 7.父类构造方法
 * 8.子类成员属性
 * 9.子类动态代码块
 * 10.子类的构造方法
 * 
//1.先静态,后动态  2.先父类,后子类

class Son extends Super{
	String a = "子类成员属性";
	{
		System.out.println(a);
		System.out.println("子类动态代码块");
	}
	
	public Son() {
		System.out.println("子类Son构造方法");
	}
	
	static String b = "子类静态属性";
	static {
		System.out.println(b);
		System.out.println("子类静态代码块");
	}
}
public class StaticCode4 {
	public static void main(String[] args) {
		new Son();
	}
}

 final使用

final: 最终的,固定不变的
修饰类:最终类-不能被继承(太监类)
修饰方法:最终方法-该方法不能被重写
修饰变量:变量变为常量

//final修饰的类,不能有子类
/*final*/ class A{
	//final修饰方法,不能被重写
	public /*final*/ void test() {
		System.out.println("A的测试方法");
	}
}

class B extends A{
	@Override
	public void test() {
		System.out.println("B的测试方法");
	}
}
public class Final1 {
	public static void main(String[] args) {
		
	}
}

final静态变量和成员变量
//修饰变量包括: 修饰成员变量,修饰静态变量,修饰局部引用变量,修饰局部基本变量
 

class MyClass{
	//1.final修饰成员变量(不常用)
	//赋值方式: 1.直接赋值  2.动态代码块  3.构造方法
	final int a;//=3; //The blank final field a may not have been initialized
	{
		//a = 5;
	}
	MyClass(){
		a = 6;
	}
	
	//2.final修饰静态变量
	//赋值方式: 1.直接赋值    2.静态代码块
	final static int b; //= 11;
	static {
		b = 12;
	}
}
public class Final2 {
	public static void main(String[] args) {
		
	}
}

final修饰局部变量
//final修饰局部变量: 包括基本变量和引用变量
 

class Student{
	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	
}
public class Final3 {
	public static void main(String[] args) {
		//1.final修饰基本变量
		final int a = 3;
		//a = 5;  //final修饰的变量,不能修改值
		
		//2.final修饰引用变量; 地址不可变;里面的存的值可变
		final int[] b = new int[3];
		b[0] = 1;
		//b = new int[4]; //地址不可变
		
		final Student st = new Student();
		//但是属性是可以变的
		st.setName("zsf");
		//st = new Student();  //地址不可变
	}
}


 
 

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到