类与对象(4)

奋斗吧
奋斗吧
擅长邻域:未填写

标签: 类与对象(4) 博客 51CTO博客

2023-07-22 18:24:13 107浏览

类与对象(4),静态变量、静态方法、代码块、类加载的加载顺序、抽象、接口、final关键字

静态变量

静态变量(类变量),用static关键字修饰的变量就是静态变量,是该类的所有实例化对象共享的变量,任何一个实例化对象去访问它时,取值和修改时,都是同一个变量

class Work{
	public static int count = 0;
  Work(){ // 无参构造器
  		count++;
  }
}
public static void main(String[] args){
 		Work w1 = new Work();
  	System.out.println(w1.count);//1
  	Work w2 = new Work();
    System.out.println(w1.count);//2
}

// 1、static静态变量是同一个类所有对象共享
// 2、static静态变量,在类加载时就已经生成了

1)静态变量与实例变量(普通属性)区别

静态变量是该类的所有对象共享的,而实例变量是每个对象独享的。

2)静态变量可以通过【类名.类变量名】或者【对象名.类变量名】来访问

推荐:使用类名.类变量名方式访问。

【前提是满足访问修饰符的访问权限和范围】

3)静态变量是在类加载时就初始化了,即使没有创建对象,只要类加载了,就可以使用静态变量。

class Work{
	public static int count = 0;
  Work(){ // 无参构造器
  		count++;
  }
}
public static void main(String[] args){
 		Work w1 = new Work();
  	System.out.println(w1.count);//1
  	Work w2 = new Work();
    System.out.println(w2.count);//2
  
  	System.out.println(Work.count);
  	// w1.count  ===  w2.count === Work.count(推荐使用) 
    //       (三者等价)
}

静态方法

静态方法(类方法),用static关键字修饰的方法就是静态方法

1)静态方法中无this的参数,而普通方法中隐含着this的参数

2)静态方法可以通过类名调用,也可以通过对象名调用。

3)静态方法中不允许使用和对象有关的关建字,比如this和super。普通方法(成员方法)可以。

4)静态方法中只能访问静态变量或静态方法。

class Work{
	public static int count = 0; // 静态变量
  public int m = 1;
  public void speak(){
        System.out.println(123);
   }
  // 静态方法
  public static void manage(){
		System.out.println(count);
    //System.out.println(m);			报错
    //speak();					报错
    //静态方法中不可以访问非静态成员变量或方法
  }
  
  Work(){ // 无参构造器
  		count++;
  }
}

代码块

代码块又称初始化块,属于类中的成员,使用{}将语句封装在方法体中

【无返回值,无方法名,没有返回对象,无参数,只有方法体】

【加载类时自动调用】

修饰符 {
	代码部分
};

// 1)修饰符 (不写)  或者  (static)
// 2)没有static修饰的代码块 ----  普通代码块
// 3)有static修饰的代码块 ----  静态代码块
// 4);号可写可不写

1)没有static修饰的代码块(普通代码块),每创建对象就会执行一次

2)有static修饰代码块(静态代码块),对类进行初始化,在类加载时自动执行,并且只会执行一次

【static代码块在类加载时执行,只会执行一次】

【普通代码块在创建对象时调用,创建一次,调用一次】

用途:

1)一般用于初始化操作

2)多个构造器中有重复语句,可以抽取到初始化块中,提高重用性

类加载中各部分的优先执行顺序

1)创建对象实例时(会加载类)

2)创建子类对象实例时,父类也会被加载(会加载类信息)

3)使用类的静态成员或静态方法时(会加载类信息)

【相同的类信息只加载一次】

//在创建对象时,类加载的顺序是:
//1、优先调用静态变量和静态代码块 (看先后顺序谁先加载)
//2、调用普通代码块和普通属性(看先后顺序谁先加载)
//3、调用构造方法

class A{

    public int a = printa();

    public static int aa =  printaa();

    public A(){
        System.out.println("A 的无参构造器被调用");
    }
    public A(int a){
        System.out.println("A 的有参构造器被调用");
    }
    private static int printaa() {
        System.out.println("A 的静态成员变量被加载");
        return 0;
    }

    private int printa() {
        System.out.println("A 的普通成员变量被加载");
        return 0;
    }

    {
        System.out.println("A 的普通代码块被加载");
    }

    static{
        System.out.println("A 的静态代码块被加载");
    }
}

public class Test {
    public static void main(String[] args) {
        A obj = new A();
        System.out.println("=================");
        A obj_1 = new A(1);
    }
}

//A 的静态成员变量被加载
//A 的静态代码块被加载
//A 的普通成员变量被加载
//A 的普通代码块被加载
//A 的无参构造器被调用
//=================
//A 的普通成员变量被加载
//A 的普通代码块被加载
//A 的有参构造器被调用

final关键字

final可以修饰类、属性、方法和局部变量,被修饰的属性又叫常量,一般均用大写字母命名

特性:

1)final修饰的属性在定义时,必须赋初始值,并且以后不可进行更改

2)final修饰的类,不可以被继承,但是可以实例化对象

3)类没有被final修饰,但是含有final修饰的方法,该方法不可重写,但是该类可以被继承

4)赋值位置(只能赋值一次!)

class Person{
  	
  
		//1、在定义时,直接赋值
  	public final String ID_CARD = "xxx";
    //2、在构造器中
    public final String NAME;
    Person(){
    	NAME = "xxx";
    }
    //3、在代码块中
    {
    	NAME = "xxx";
    }
    
  // 如果final修饰的属性是静态的  ---  不可以在构造器中赋值
  //1、定义时
  public final static int K = 1;
  //2、在静态代码块中
  static {
    	K = 1;
  }
}

5)通常,final修饰类了,其方法没有必要再使用final进行修饰了

6)final不可以修饰构造器

7)小知识:包装类Integer、Double、Float、String等等都是final修饰的

使用场景:

在某些情况下,程序员可能有以下需求,就会使用final关键字进行修饰

1)当不希望类被继承时

2)当不希望父类的某个方法被子类覆盖/重写(override)时

3)当不希望类的的某个属性的值被修改

4)当不希望某个局部变量被修改

抽象类

在抽象类中给出方法定义,让子类完成重写,在工程项目中起很大作用,其没有确定的方法体

实例:【抽象类给出方法声明,继承抽象类的子类完成具体方法体】


abstract class Animal{
    void eat();
    void drink();
    void run();
}
class Dog extends Animal{

    @Override
    public void eat() {
        System.out.println("狗 eat");
    }

    @Override
    public void drink() {
        System.out.println("狗 drink");
    }

    @Override
    public void run() {
        System.out.println("狗 run");
    }
}
class Cat extends Animal{
    @Override
    public void eat() {
        System.out.println("猫 eat");
    }

    @Override
    public void drink() {
        System.out.println("猫 drink");
    }

    @Override
    public void run() {
        System.out.println("猫 run");
    }
}

特点:

1)抽象类不能被实例化

2)抽象类可以没有abstract修饰的方法

3)一旦包含了abstract修饰的方法,这个类必须声明为abstract

4)abstract只能修饰类和方法,修饰方法时没有方法体

5)一个类继承了抽象类,必须实现抽象类的所有抽象方法,除非这个类也声明为abstract类

6)抽象方法不可使用private、static、final来修饰

【抽象方法的本质就是在子类中被重写,这些关键字与其相违背】

接口

接口就是给出一些没有实现的方法,封装到一起,到某个类使用的时候,在根据具体情况把这些方法进行实现

特点:

1)接口可以有自己的属性和方法

2)接口不可以被实例化

3)接口中所有的方法是public方法,抽象方法可以不用abstract修饰

4)一个普通类实现接口,就必须将该接口的所有方法都实现

5)抽象类实现接口,可以不用实现借口的方法

6)一个类可以实现多个接口,接口名用,号隔开

7)接口中的属性,默认为public static final 修饰

int a = 10;   ----  public static final int a =10;

8)一个接口不能继承其他的类,但是可以继承多个别的接口

9)接口的修饰符只能public 和默认,这点与类的修饰符相同

实例:

// 主函数
public class Test {
    public static void main(String[] args) {
        Live L = new Live();
        Dog d = new Dog();
        Cat c = new Cat();
        
        L.living(d);
        L.living(c);
    }
}
// 接口 interface关键字 进行修饰
interface Animal{
    String NAME = "动物";
    // 默认等价于 public static final String NAME = "动物"
    public abstract void eat();
    public abstract void drink();
    public abstract void run();
}
// 接口实现类
class Dog implements Animal{
    @Override
    public void eat() {
        System.out.println("狗 eat");
    }

    @Override
    public void drink() {
        System.out.println("狗 drink");
    }

    @Override
    public void run() {
        System.out.println("狗 run");
    }
}
// 接口实现类
class Cat implements Animal{
    @Override
    public void eat() {
        System.out.println("猫 eat");
    }

    @Override
    public void drink() {
        System.out.println("猫 drink");
    }

    @Override
    public void run() {
        System.out.println("猫 run");
    }
}
class Live{
    public void living(Animal animal){
        animal.eat();
        animal.drink();
        animal.run();
    }
}


好博客就要一起分享哦!分享海报

此处可发布评论

评论(0展开评论

暂无评论,快来写一下吧

展开评论

您可能感兴趣的博客

客服QQ 1913284695