11-Java面向对象高级

类变量和类方法

  • 类变量
    类变量快速入门
    类变量,也叫静态变量,所有对象均共享此变量,static修饰
  • 不管static变量放在那里,有可能放在堆,也有可能放在方法区,jdk8以上放在堆,之前的版本可能放在静态域方法区
  • static变量是同一类所有对象共享
  • static类变量在类加载的时候就生成了,所有没有创建对象实例也可以访问
  • static类变量除了静态方法,在普通方法可以用this和super修饰
package com.hspedu.static_;

public class VisitStatic {
    public static void main(String[] args) {
        // 类名.类变量名
        System.out.println(A.name);
    }
}

class A{
    //
    public static String name = "韩顺平教育";
}
  • static依然准守相应的访问权限
package com.hspedu.static_;

public class ChildGame {
    public static void main(String[] args) {
//        int count = 0;
        Child child1 = new Child("白骨精");
//        count++;
        child1.count++;
        Child child2 = new Child("狐狸精");
//        count++;
        child2.count++;

        //类变量可以通过类名进行访问
        System.out.println("共有" + Child.count + "小朋友加入游戏");
        System.out.println("共有" + child1.count + "小朋友加入游戏");
        System.out.println("共有" + child2.count + "小朋友加入游戏");



    }
}

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

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

  • 类变量使用细节

  • 类方法

  • 类方法是使用场景

package com.hspedu.static_;

public class StaticMethod {
    public static void main(String[] args) {
        // 创建两个学生对象,交学费
        Stu tom = new Stu("tom");
        tom.payFee(100);
        Stu mary = new Stu("mary");
        mary.payFee(200);


        // 输出总方法
        Stu.showFee();
    }
}


class Stu{
    private String name; // 普通成员
    // 定义一个静态变量,累计学生的学费
    private static double fee = 0;

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

    // 1.放方法使用了static修饰后,该方法就是静态方法
    // 2.静态方法就可以访问静态变量
    public static void payFee(double fee){
        Stu.fee += fee;
    }

    public static void showFee(){
        System.out.println("总学费:" + Stu.fee);
    }
}
  • 静态方法只能访问静态方法和静态变量
  • 静态方法不能访问对象相关的关键字,比如this或者super,不能访问普通成员(非静态成员)
  • 普通方法可以访问静态方法和静态变量

理解main方法语法

代码块

  • 我们不管调用哪个构造器,都会优先调用代码块
  • 对构造器的一种补充机制,可以初始化一些操作
  • 代码块的调用顺序优先于构造器

  • 代码快的使用细节

    -static代码块是在类加载的时候执行的,而且只会执行一次
  • 类加载的情况
    1.创建一个对象实例的时候
    2.子类继承父类,创建子类对象,优先加载父类
    3.使用静态变量或者方法的时候

-普通代码块,在创建对象实例时会被隐式的调用,被创建一次就会调用一次,如果只是使用静态成员,普通代码块不会执行

  • 普通代码块可以理解就是构造器的补充

  • 细节4

  • 创建一个对象时,在一个类的调用顺序
    1.调用静态代码块和静态属性初始化:静态代码块和静态属性初始化是一样的,如果有多个静态代码块和多个静态变量初始化,按照定义的顺序调用
    2.调用普通代码块和普通属性的初始化
    3.调用构造方法
    4.构造器的前面其实隐藏了super和普通代码块,静态相关的代码块和属性初始化时,在类加载时就执行完毕了

    创建一个子类对象(继承)调用顺序
    1.父类的静态代码块,父类的静态属性(同等优先级)
    2.子类的静态代码块,子类的静态属性
    3.父类的普通代码块,父类普通属性
    4.父类的构造方法
    5.子类的普通代码块,子类的普通属性
    6.子类的构造器

package com.hspedu.codeblock_;

public class CodeDetail03 {
    public static void main(String[] args) {
        BBB bbb = new BBB();
    }
}

class AAA{
    private static int n1 = getN1();
    private int n2 = getN22();
    static int getN1(){
        System.out.println("执行父类的静态方法getN1"); // 1
        return 100;
    }
    static void printN1(){
        System.out.println("执行父类的静态方法");
    }

    int getN22(){
        System.out.println("执行父类普通方法getN2()"); //5
        return 300;
    }

    static {
        System.out.println("AAA父类的静态代码块"); // 2
    }

    {
        System.out.println("AAA父类普通代码块"); // 6
    }

    public AAA(){
        System.out.println("AAA 父类构造器被调用"); // 7
    }
}

class BBB extends AAA{
    private static  int n1 = getN1();
    private int n2 = getN2();
    static int getN1(){
        System.out.println("子类getN1静态属性"); // 3
        return 100;
    }
    static void printn2(){
        System.out.println("子类的静态方法");
    }
    int getN2(){
        System.out.println("子类getN2的普通方法");//8
        return 200;
    }

    static {
        System.out.println("子类的静态代码块"); // 4
    }

    {
        System.out.println("BBB子类普通代码块"); // 9
    }
    public BBB(){
        System.out.println("BBB子类构造器方法"); // 10
    }
}

单例设计模式



  • 饿汉式单例模式
package com.hspedu.single_;

public class SingleTon01 {
    public static void main(String[] args) {
//        GirlFriend xh = new GirlFriend("小红");
//        GirlFriend xb = new GirlFriend("小白");
        // 通过类方法获取一个对象
        GirlFriend instance =  GirlFriend.getInstance();
        System.out.println(instance);

    }
}

// 有一个类,GirlFriend,只能有一个女友
class GirlFriend{
    // 如何保证创建一个girlfriend


    private String name;
    // w为了能够在静态方法中使用,需要修饰为static
    private static GirlFriend gf = new GirlFriend("小红红");
    // 构造器私有化
    // 2.在类的内部创建对象
    // 3.提供一个公共的静态方法,可以返回gf对象
    private GirlFriend(String name) {
        this.name = name;
    }

    public static GirlFriend getInstance(){
        return gf;
    }

}
  • 饿汉式可能导致创建了对象但是没有使用
package com.hspedu.single_;
/*
演示懒汉式
 */
public class SingalTon02 {
    public static void main(String[] args) {
        System.out.println(Cat.n1);
    }
}

// 希望在程序运行过程中,只创建一个猫
class Cat{
    private String name;
    public static int n1 = 999;
    // 步骤
    //1. 构造器私有化
    // 2.定义一个静态属性
    // 3.使用public的static方法,可以返回一个Cat对象
    private static Cat cat;
    private Cat(String name) {
        System.out.println("构造器调用");
        this.name = name;
    }

    public static Cat getInstance(){
        if(cat == null){
            cat = new Cat("小可爱");

        }
        return cat;
    }
}
  • 饿汉式和懒汉式的区别

final关键字

final最后的最终的,可以修饰类,属性,方法,局部变量
final的用法

  • 不希望类被继承,可以用final
  • 不希望父类的方法被子类覆盖或者重写,用final
  • 不希望父类的某个属性修改,用final
  • 不希望某个局部变量修改,用final

package com.hspedu.final_;

public class Final01 {
    public static void main(String[] args) {
        E e = new E();
//        e.TAX_RATE = 0.1;
//        CC cc = new CC();

        EE ee = new EE();
        ee.cal();
        
    }
}

// 如果我们使用A类不能被其他类继承
// 可以使用final修饰A类

final class A{

}

//class B extends A {}

class C {
    public void hi(){

    }
}

class D extends C{
    @Override
    public void hi() {
        System.out.println("重写了父类方法");
    }
}

class E{
    public final double TAX_RATE = 0.08;
}

class F {
    public void cry(){
        final double NUM = 0.01;
//        NUM = 0.9;
        System.out.println("NUM=" + NUM);
    }
}
class AA{
    /*
    定义的位置,在定义时
    构造器
    代码块
     */
    public final int n1 = 1;
    public final int n2;
    public final int n3;

    {
        n3 = 1;
    }

    public AA(){
        n2 =  3;
    }
}

class BB{
    /*
    final修饰静态,初始化的位置只能是:
    1.定义
    2.在静态代码块
     */

    public static final double TAX_RATE = 99;
    public static final double TAX_RATE2;

    static {
        TAX_RATE2 = 4;
    }
}

// final类不继承,但是可以实例化对象
final class CC{}

// 如果类不是final,但是含有final,该方法不能重写,但是可以继承使用
class DD {
    public final void cal(){
        System.out.println("123");
    }
}
class EE extends DD{}

抽象类



  • 模版设计模式
package com.hspedu.abstract_;

abstract class Template {
    // 计算任务
    public abstract void job();

    public void calucateTime(){
        // 得到开始的时间
        long start = System.currentTimeMillis();

        job();
        //
        // 得到结束的时间
        long end = System.currentTimeMillis();
        System.out.println("AA执行时间" + (end - start));
    }

}

接口

内部类

posted @ 2022-01-07 22:46  心远志高  阅读(30)  评论(0编辑  收藏  举报