您的当前位置:首页正文

JAVA篇04 —— 面向对象核心部分

来源:九壹网

 欢迎来到我的主页:【

本篇文章收录于专栏【

如果这篇文章对你有帮助,希望点赞收藏加关注啦~

目录


1 类变量static

类变量也叫静态变量/静态属性,是该类的所有对象共享的变量,任何一个该类的对象去访问它时,取到的都是相同的值,同样任何一个该类的对象去修改它时,修改的也是同一个变量。这个从前面的图也可看出来。

package day111;

/**
 * @ClassName staticClass
 * @Description
 * @Date 2024/11/26 9:13
 * @Version V1.0
 */
public class staticClass {
    public static void main(String[] args) {
        int count = 0;
        Child child1 = new Child("白骨精");
        child1.join();
        child1.count++;
        Child child2 = new Child("狐狸精");
        child2.join();
        child2.count++;
        Child child3 = new Child("老鼠精");
        child3.join();
        child3.count++;
        System.out.println("共有" + Child.count + " 小孩加入了游戏...");
        System.out.println("child1.count=" + child1.count);//3
        System.out.println("child2.count=" + child2.count);//3
        System.out.println("child3.count=" + child3.count);//3
    }
}


class Child { //类
    //定义一个变量 count ,是一个类变量(静态变量) static 静态
    //该变量最大的特点就是会被 Child 类的所有的对象实例共享
    public static int count = 0;
    private String name;

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

    public void join() {
        System.out.println(name + " 加入了游戏..");
    }
}

1.1 static方法

当方法中不涉及对象成员的时候,建议将方法写成static,如utils类。开源的Math、Arrays、Collection类源码如下:

技巧:通用方法开发为静态,方便使用。

注意:


1.2 main方法 

在 main()方法中, 我们可以直接调用 main 方法所在类的静态方法或静态属性。但是, 不能直接访问该类中的非静态成员, 必须创建该类的一个实例对象后, 才能通过这个对象去访问类中的非静态成员。


2 初始化块

Static Initialization Block:

属于类中的成员[即 是类的一部分],类似于方法,将逻辑语句封装在方法体中,通过{}包围起来。
但和方法不同,没有方法名没有返回,没有参数,只有方法体,而且不用通过对象或类显式调用,而是加载类时或创建对象时隐式调用。

public class Demo {
   private static String msg = "hello";
 
   static {
       // 初始化
       msg = "world";
       System.out.println("静态初始化块");
   }
 
   public static void main(String[] args) {
       System.out.println(msg);
   }
}

Instance Initialization Block:

public class Demo {
   private String msg = "";
 
   {
       // 初始化
       msg = "B";
   }
 
}

3 单例模式

涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。

这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。确保一个类只有一个实例,并提供了一个全局访问点来访问该实例。

  • 1、单例类只能有一个实例。
  • 2、单例类必须自己创建自己的唯一实例。
  • 3、单例类必须给所有其他对象提供这一实例。

 优点:内存中只有一个实例,减少内存开销,尤其是频繁创建和销毁实例时(如管理学院首页页面缓存)。避免资源的多重占用(如写文件操作)。

缺点:没有接口,不能继承。与单一职责原则冲突。

3.1 懒汉式

//最基本的方式,但是线程不安全(没有加锁)。
public class Singleton {  
    private static Singleton instance;  
    private Singleton (){}  //构造器私有化
    public static Singleton getInstance() {  
        if (instance == null) {  
            instance = new Singleton();  
        }  
        return instance;  
    }  
}

//加锁
public class Singleton {  
    private static Singleton instance;  
    private Singleton (){}  
    public static synchronized Singleton getInstance() {  
        if (instance == null) {  
            instance = new Singleton();  
        }  
        return instance;  
    }  
}

优点:第一次调用才初始化,避免内存浪费。
缺点:必须加锁 synchronized 才能保证单例,但加锁会影响效率。
getInstance() 的性能对应用程序不是很关键(该方法使用不太频繁)。

3.2 饿汉式

public class Singleton {  
    private static Singleton instance = new Singleton();  
    private Singleton (){}  
    public static Singleton getInstance() {  
    return instance;  
    }  
}
优点:没有加锁,执行效率会提高。
缺点:类加载时就初始化,浪费内存。容易产生垃圾对象

3.3 Double-Checkd locking

public class Singleton {  
    private volatile static Singleton singleton;  
    private Singleton (){}  
    public static Singleton getSingleton() {  
    if (singleton == null) {  
        synchronized (Singleton.class) {  
            if (singleton == null) {  
                singleton = new Singleton();  
            }  
        }  
    }  
    return singleton;  
    }  
}

采用双锁机制,安全且在多线程情况下能保持高性能。

3.4 登记式/static类

public class Singleton {  
    private static class SingletonHolder {  
    private static final Singleton INSTANCE = new Singleton();  
    }  
    private Singleton (){}  
    public static final Singleton getInstance() {  
        return SingletonHolder.INSTANCE;  
    }  
}

3.5 枚举

public enum Singleton {  
    INSTANCE;  
    public void whateverMethod() {  
    }  
}
更简洁,自动支持序列化机制

4 final关键字

final是一个关键字,可以用于修饰类,成员变量,成员方法。

特点

  1. 它修饰的类不能被继承。
  2. 它修饰的成员变量是一个常量。
  3. 它修饰的成员方法是不能被子类重写的。

final修饰的常量定义一般都有书写规范,被final修饰的常量名称,所有字母都大写。public final double TAX_RATE=0.08;

final修饰成员变量,必须初始化,初始化有两种

  • 显示初始化;
  • 构造方法初始化。
    但是不能两个一起初始化

final和private的区别

  1. final修饰的类可以访问;
    private不可以修饰外部类,但可以修饰内部类(其实把外部类私有化是没有意义的)。
  2. final修饰的方法不可以被子类重写;
    private修饰的方法表面上看是可以被子类重写的,其实不可以,子类是看不到父类的私有方法的。
  3. final修饰的变量只能在显示初始化或者构造函数初始化的时候赋值一次,以后不允许更改;
    private修饰的变量,也不允许直接被子类或一个包中的其它类访问或修改,但是他可以通过set和get方法对其改值和取值。

5 抽象类和接口

  1. 抽象类不能实例化
  2. 抽象类不一定要包含抽象方法
  3. 一旦类包含abstract方法,必须声明为抽象类
  4. abstract只能修饰类、方法
  5. 抽象类的本质还是类,可以有静态属性、非抽象方法、构造器等。
  6. 抽象方法不能有主体,如:abstract void get(){ };
  7. 一个类Extends抽象类,必须实现所有抽象方法。除非它也是abstract类。
  8. 抽象方法不能用private、static、final修饰
  1. interface比抽象类更抽象,它里面的方法都不能有方法体。
  2. 接口体现了多态和高内聚低耦合设计思想。jdk8之后interface可以有static方法和默认方法(可以有具体实现)。
  3. 接口不能被实例化
  4. 接口的方法如void a();实际上是public abstract void a();
  5. 抽象类实现接口可以不用实现接口方法。
  6. 一个普通类实现接口必须实现所有的类,可以实现多个接口。
  7. 接口中的属性int a=10;实际上是public static final int a=10;
  8. 接口不能继承类,但是可以继承接口
  9. 接口的修饰符只能是default和public


5.1 接口的多态

package day111;

interface TestInerface {
    void print();
}

/**
 * @ClassName InterfacePoly
 * @Description
 * @Date 2024/11/27 14:37
 * @Version V1.0
 */
public class InterfacePoly {
    public static void main(String[] args) {
        TestInerface testInerface = new TestInerfaceA();
        //接口类型的变量 testInterface可以指向 实现了 IF 接口类的对象实例
        testInerface.print();//输出A
        testInerface = new TestInerfaceB();
        testInerface.print();//输出B

        //父类类型的变量 a 可以指向 继承 AAA 的子类的对象实例
        TestExtends testExtends = new TestExtendsA();
        testExtends = new TestExtendsB();
    }
}

class TestInerfaceA implements TestInerface {
    @Override
    public void print() {
        System.out.println("I'm TestInerfaceA");
    }
}

class TestInerfaceB implements TestInerface {
    @Override
    public void print() {
        System.out.println("I'm TestInerfaceB");
    }
}

class TestExtends {
}

class TestExtendsA extends TestExtends {
}

class TestExtendsB extends TestExtends {
}

6 内部类(※※)

因篇幅问题不能全部显示,请点此查看更多更全内容

Top