Java笔记之面向对象 下(十二)

一、类变量和类方法

1.类变量

(1)基本介绍:

类变量(静态变量):类变量是该类所有对象共享的变量,任何一个类的对象去访问它是,取到的都是相同的值,同样任何一个该类的对象去修改它是,修改的也是同一个变量,加上static 为类变量或者静态变量。

语法格式:

  1. 访问修饰符 static 数据类型 变量名;【推荐】
  2. static 数据类型 变量名;

访问格式:

  1. 类名.类变量名;【推荐】
  2. 对象名.类变量名;

需要注意访问修饰符的权限

(2)使用细节

  1. 当某个类共享一个变量时,可以考虑使用类变量
  2. 类变量被该类的所有对象所共享,而普通变量(实例变量)是该类每个对象独享的
  3. 加static称为类变量或静态变量,否则称为实例变量
  4. 类变量可以通过,类.类变量名访问 或 类对象.类变量名访问,普通变量则不行
  5. 类变量在加载类时就已经初始化了
  6. 类变量的生命周期随着类的加载开始,随着类的消亡而销毁
public class test1 {
    public static void main(String[] args) {
        System.out.println(A.x);    //正确10
        System.out.println(new A().x);  //正确10
//        System.out.println(A.y);    //错误
    }
}

class A{
    public static int x = 10;   //静态变量
    public int y = 20;  //普通变量
}

2.类方法

(1)基本介绍:
类方法:又叫静态方法,与类变量类似

语法格式:

  1. 访问修饰符 static 数据返回类型 方法名(){ }【推荐】
  2. static 访问修饰符 数据返回类型 方法名(){ }

访问格式:

  1. 类名.类方法名();【推荐】
  2. 对象名.类方法名();

需要注意访问修饰符的权限

使用场景:

当方法中不涉及到任何对象的相关的成员时,则可以讲方法设置成静态方法,提高开发效率,即不创建对象也可以调用某个方法

(2)使用细节

  1. 类方法(静态方法)和普通方法都是随着类的加载而加载
  2. 类方法中无this的参数,普通方法中隐含着this的参数
  3. 类方法中不允许使用和对象有关的关键字,比如this和super。普通方法可以。
  4. 类方法中只能访问静态变量或静态方法,普通方法则都可以访问 前提:遵守访问修饰符权限
public class test1 {
    public static void main(String[] args) {
//        A.demo1();  //错误 private访问修饰符
        A.test1();
//        A.test();   //错误,该方法为普通方法
        new A().test();     //创建对象可以调用普通方法
    }
}

class A{
    private static int x = 10;   //静态变量
    private int y = 20;  //普通变量
    private void demo(){};   //普通方法
    private static void demo1(){};   //静态方法

    //普通方法
    public void test(){
        System.out.println(this.y);
        System.out.println(x+y);    //普通和静态变量都可以访问
        demo(); //可以访问普通方法
        demo1();  //可以访问静态方法
    }

    //静态方法
    public static void test1(){
//        System.out.println(this.y); //错误  不可以使用this
//        System.out.println(y);  //错误  不能访问普通变量
//        demo(); //错误  不能访问普通方法
        System.out.println(x);  //可以访问静态变量
        demo1();    //可以访问静态方法
    }
}

二、代码块

1.代码块

代码块:又称初始化块,属于类中的成员 即类的一部分,类似于方法,将逻辑语句封装在方法体重,通过{}包起来

与方法的区别:没有方法名、没有返回值、没有参数,只有方法体,不能通过对象或类显示调用,而是在类加载时,或者创建对象时隐士调用

使用场景:如果多个构造器中都有重复的语句,可以抽取到初始化代码块中,提高代码的复用性

基本格式:
[修饰符]{
  代码;
}

修饰符只能是static,即代码块分为两类,带static称为静态代码块,不带static的称为普通代码块

代码块调用的顺序优先于构造器

2.使用细节☆

  1. 静态代码块就是在代码块前面加static,作用就是对类进行初始化,随着类的加载而执行,并且只会执行一次;而普通代码块每创建一个对象,就执行一次
  2. 类什么时候加载
    ①创建对象实例时
    ②创建子类对象实例时,父类也会被加载
    ③使用类的静态成员时(静态属性,静态方法)
  3. 如果使用类的静态成员时,普通代码块并不会执行
  4. 静态代码块和静态成员初始化调用优先级一样,普通代码块和普通成员初始化调用优先级一样
  5. 静态代码块只能调用静态成员,普通代码块可以调用任意成员
public class test1 {
    public static void main(String[] args) {
//        new A();  //对象被创建时,该类中的静态方法被调用
//        new B();  //子类创建时,父类的静态方法也会被调用
        System.out.println(A.a);    //使用静态成员时,静态方法也会被调用
    }
}

class A{
    public static int a=10;
    //注意:静态方法只会被执行一次
    static {
        System.out.println("A类静态代码块被调用!");
    }
}

class B extends A{}
  1. 构造器的最前面,其实隐含了super()和调用普通代码块,也就是说在创建对象时 第一步调用了super 第二步就是调用普通代码块
public class test1 {
    public static void main(String[] args) {
        new A();    //输出:普通代码块 构造方法
    }
}

class A{
    //普通代码块
    {
        System.out.println("普通代码块");
    }
    
    public A(){
        //super
        //静态代码块
        System.out.println("构造方法");
    }
}

三、单例设计模式

1.基本介绍

设计模式:表示在大量的实践中总结和理论化之后优化选的代码结构、编程风格、以及解决问题的思考方式

单例模式:就是采取一定的方法保证在整个软件系统中,对某个类只能存在一个对象实例,并且该类只能提供一个取得其对象实例的方法

单例模式分为两种:饿汉式和懒汉式

2.饿汉式

饿汉式步骤如下:

  1. 构造方法私有化(为了防止用户直接new)
  2. 在类内部创建一个static静态属性对象
  3. 向外提供一个静态的公共方法。如:public static Person getPerson(){}
public class test1 {
    public static void main(String[] args) {
        //类名调用静态方法getPerson()
        Person person = Person.getPerson();    //构造器被调用
        System.out.println(person); //自动调用toString方法

        Person person1 = Person.getPerson();    //构造器只会被调用一次
        System.out.println(person1); //自动调用toString方法
        System.out.println(person.equals(person1));     //两者是同一个对象
    }
}

class Person{
    private String name;

    //为了能在静态方法中,返回Person对象,则修饰符需要为static
    private static Person Person= new Person("张三");

    //private私有构造器类外就不能new创建对象
    private Person(String name) {
        this.name = name;
        System.out.println("构造器被调用!");
    }

    //获取Person对象方法
    public static Person getPerson() {
        return Person;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                '}';
    }
}

2.懒汉式

饿汉式步骤如下:

  1. 构造方法私有化(为了防止用户直接new)
  2. 在类内部创建一个static静态属性对象
  3. 向外提供一个静态的公共方法返回该对象
public class test1 {
    public static void main(String[] args) {
        //类名调用静态方法getPerson()
        Person person = Person.getPerson();    //构造器被调用
        System.out.println(person); //自动调用toString方法

        Person person1 = Person.getPerson();    //构造器只会被调用一次
        System.out.println(person1); //自动调用toString方法
        System.out.println(person.equals(person1));     //两者是同一个对象
    }
}

class Person{
    private String name;

    //为了能在静态方法中,返回Person对象,则修饰符需要为static
    private static Person Person;

    //private私有构造器类外就不能new创建对象
    private Person(String name) {
        this.name = name;
        System.out.println("构造器被调用!");
    }

    //获取Person对象方法
    public static Person getPerson() {
        if (Person == null){
            Person = new Person("张三");
        }
        return Person;  //如果该对象不等于null则直接返回上次创建的对象
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                '}';
    }
}

3.饿汉式和懒汉式的区别

  1. 两者创建对象的时机不同,饿汉式是在类加载时就创建了对象,而懒汉式是在使用时才创建
  2. 饿汉式不存在线程安全问题,懒汉式存在线程安全问题。
  3. 饿汉式存在浪费资源的可能,而懒汉式则不存在这问题,因为懒汉式在使用时对象才创建

四、final关键字

1.基本介绍

final:中文意思最终的,可以修饰类、属性、方法以及局部变量

使用场景:

  1. 当不希望类被继承时,可以用final修饰该类
  2. 当不希望父类的某个方法被 重写 或者 覆盖 时,可以用final修饰该方法
  3. 当不希望类的某个属性(全局变量)被修改时,可以用final修饰该属性
  4. 当不希望某个局部变量被修改时,可以用final修饰该变量

2.快速入门

public class test1 {
    public static void main(String[] args) {
        E e = new E();
//        e.a = 20; //错误,因为属性(全局变量)a为final
    }
}
//情况一
final class A{}
//class B extends A{} //错误,因为A类为final

class C{
    public final void test(){}
}
//情况二
class D extends C{
    //错误,因为父类方法test()为final
//    @Override
//    public void test() {
//        super.test();
//    }
}
//情况三
class E{
    public final int a = 30;
}
//情况四
class F{
    public void test(){
        final int x = 20;
//        x = 10;   //错误,因为局部变量x为final
    }
}

3.使用细节

  1. final修饰的属性在定义的时候,必须赋初始值,并且以后不能修改
  2. final修饰的属性时初始化的位置只能在
    ① 定义时赋值
    ② 在构造器外定义,在构造器中赋值
    ③ 在代码块外定义,在代码块中赋值
  3. 如果final修饰的属性是静态时,则初始化的位置只能在
    ① 定义时赋值
    ② 在静态代码块外定义,在静态代码块中赋值
  4. 一般来说,如果一个类已经是final类了,就没有必要再将方法修饰程final方法
  5. final不能修饰构造方法
  6. final和static往往搭配使用,效率更高
  7. 包装类(Integer,Double,Float,Boolean等都是final),String也是final类
public class test1 {
    public static void main(String[] args) {
        A testA = new A();
        System.out.println(testA.x+" "+testA.y+" "+testA.z+" ");    //10 20 30
        System.out.println(A.a+" "+A.b);    //10 20
    }
}

class A{
    //非静态
    public final int x = 10;    //在定义时赋值
    public final int y;         //在构造器中赋值
    public final int z;
    //静态
    public static int a = 10;
    public static final int b;

    //构造器
    public A(){
        y = 20;
    }
    //代码块
    {
        z = 30;
    }

    //静态代码块
    static {
        b = 20;
    }
}

五、抽象类☆

1.基本介绍

抽象类:用abstract关键字修饰的类称为抽象类

语法格式:
访问修饰符 abstract 类名{ }

抽象方法:当父类的一些方法不能确定时,可以用abstract关键字来修饰该方法,这个方法就是抽象方法

语法格式:
访问修饰符 abstract 返回类型 方法名( 参数列表 );

1.注意:抽象方法没有方法体
2.抽象类的价值更多作用是在于设计,是设计者设计好后,让子类继承并事项抽象类
3.简化了代码的复杂性,提供代码的复用性

抽象类面试官比较爱问的知识点,在框架和设计模式使用较多

2.快速入门

定义抽象类和抽象方法

abstract class A{	//抽象类
    String name;
    int age;
    abstract public void test();	//抽象方法
}

3.使用细节

  1. 抽象类不能被实例化
  2. 抽象类可以没有抽象方法,但抽象方法必须在抽象类中
  3. abstract 只能修饰类和方法,不能修饰属性和其它
  4. 抽象类中可以有除抽象方法外的其它属性、方法等
  5. 抽象方法不能有方法主体
  6. 如果一个类继承了抽象类,则它必须实现抽象类的所有抽象方法,除非这个类也声明为abstract 类
  7. 抽象方法不能使用private、final和static来修饰,因为这些关键字都是和重写相违背的
public class test1 {
    public static void main(String[] args) {
        //细节1
//        new A();    //错误
    }
}

abstract class A{
    String name;
    int age;
    abstract public void test();

    //细节3
//    abstract int x; //错误

    //细节7
//    abstract private void test1();    //错误
//    final abstract void test2();      //错误
//    abstract static void test3();     //错误
}

//细节2
class D{
//    abstract public void test();  //错误
}

//细节6
class B extends A{
    @Override
    public void test() {
        System.out.println("重写父类的抽象方法");
    }
}
//细节6
abstract class C extends A{}

案例练习

public class test1 {
    public static void main(String[] args) {
        Manager manager = new Manager("张三", 10, 50000, 1000);
        manager.work();

        CommonEmployee employee = new CommonEmployee("李四", 20, 30000);
        employee.work();
    }
}

abstract class Employee{
    String name;
    int id;
    int salary; //薪水

    public Employee(String name, int id, int salary) {
        this.name = name;
        this.id = id;
        this.salary = salary;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getSalary() {
        return salary;
    }

    public void setSalary(int salary) {
        this.salary = salary;
    }

    public abstract void work();    //抽象类
}

class Manager extends Employee{
    private double bonus;   //奖金

    public Manager(String name, int id, int salary, double bonus) {
        super(name, id, salary);
        this.bonus = bonus;
    }

    public double getBonus() {
        return bonus;
    }

    public void setBonus(double bonus) {
        this.bonus = bonus;
    }

    @Override
    public void work() {
        System.out.println("经理 "+getName()+" 工作中~");
    }
}

class CommonEmployee extends Employee{
    public CommonEmployee(String name, int id, int salary) {
        super(name, id, salary);
    }

    @Override
    public void work() {
        System.out.println("普通员工 "+getName()+" 工作中~");
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王博1999

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值