• Java学习笔记(三):抽象类


    一、类变量和类方法

    在创建对象的时候,会在堆中创建一个class对象,static变量是同一个类所有对象共享。

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

    类变量可以通过类名.类变量名 对象名.类变量名来访问。

    类方法的调用类名.类方法名 对象名.类方法名类方法中无this参数,普通方法中隐含着this参数。

    • 类方法中只能访问静态变量和静态方法;普通成员方法既可以访问非静态成员,也可以访问静态方法。(遵守访问权限)

    二、main方法语法

    public static void main(String[] args){}
    
    • 1

    jvm需要调用类的main()方法,所以该方法访问权限必须是public,执行时不必创建对象,所以为static

    • 该方法接收String类型的数组参数,该数组中保存执行Java命令时所传递给所运行的类的参数。

    • 在main()方法中,可以直接调用main方法所在类的静态方法和静态属性

    • 不能直接访问该类中的非静态成员,必须创建该类的一个实例对象之后,才可以通过这个对象去访问类中的非静态成员。

    三、代码块

    把相同的语句都都放入到一个代码块之中,不管调用哪个构造器,创建对象,都会先调用代码块的内容。

    static代码块的作用是对类进行初始化,随着类的加载而执行,并且只会执行一次;普通代码块每创建一个对象就执行一次。

    • 创建对象实例时
    • 创建子类对象实例,父类也会被加载
    • 使用类的静态成员时(静态属性、静态方法)

    在创建一个类时,先调用静态代码块和静态属性初始化,按定义的顺序调用。再调用普通代码块和普通属性的初始化,按定义的顺序调用。再调用构造方法(构造器)

    构造器的最前面隐含了super()和调用普通代码块。

    public class test {
        public static void main(String[] args) {
            Base base = new Base();
            System.out.println("---------------");
            Base base1 = new Base();
            System.out.println("---------------");
            Base base2 = new Base();
        }
    }
    
    class Base{
        {
            System.out.println("11111");
            System.out.println("22222");
        }
    
        static {
            System.out.println("000000");
        }
        
        public Base() {
            System.out.println("33333");
        }
    }
    
    000000
    11111
    22222
    33333
    ---------------
    11111
    22222
    33333
    ---------------
    11111
    22222
    33333
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    在创建一个子类时(继承关系),调用顺序:

    1. 父类的静态属性和静态代码块
    2. 子类的静态属性和静态代码块
    3. 父类的普通代码块和普通属性初始化
    4. 父类的构造方法
    5. 子类的普通代码块和普通属性初始化
    6. 子类的构造方法

    静态代码块只能调用静态成员,普通代码块可以调用任意成员

    四、单例设计

    在整个软件系统中,对于某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法。

    • 构造器私有化
    • 类的内部创建对象
    • 向外暴露一个静态的公共方法
    package single;
    
    public class singleTon01 {
        public static void main(String[] args) {
            S instance = S.getInstance();
            S instance1 = S.getInstance();
            
            System.out.println(instance.hashCode());
            System.out.println(instance1.hashCode());
        }
    }
    
    class S{
        private String name;
    
        private S(String name) {
            this.name = name;
        }
    
        private static S s = new S("single");
    
        public static S getInstance(){
            return s;
        }
    }
    
    381259350
    381259350
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 构造器私有化
    • 定义一个static静态属性对象
    • 提供一个public的static方法,返回一个类的对象
    package single;
    
    public class singleTon02 {
        public static void main(String[] args) {
            SS instance = SS.getInstance();
            System.out.println(instance);
        }
    }
    
    class SS{
        private String name;
    
        private SS(String name) {
            this.name = name;
        }
    
        private static SS s;
    
        public static SS getInstance(){
            if (s == null){
                s = new SS("single");
            }
            return s;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    一个是在类加载时就创建了对象实例(浪费资源的可能),而另一个是在使用时才创建(存在线程安全问题)

    //java.lang.Runtime
    public class Runtime {
        private static final Runtime currentRuntime = new Runtime();
    
        private static Version version;
    
        /**
         * Returns the runtime object associated with the current Java application.
         * Most of the methods of class {@code Runtime} are instance
         * methods and must be invoked with respect to the current runtime object.
         *
         * @return  the {@code Runtime} object associated with the current
         *          Java application.
         */
        public static Runtime getRuntime() {
            return currentRuntime;
        }
    
        /** Don't let anyone else instantiate this class */
        private Runtime() {}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    五、final关键字

    修饰类、属性、方法和局部变量

    • 不希望类被继承
    • 不希望父类的某个方法被子类覆盖
    • 不希望类的某个属性的值被修改
    • 不希望某个局部变量被修改
    class A{
        public final int i = 10;
    
        public final void hi() {
        }
    }
    
    final class B extends A{
        @Override
        public void hi() {//无法重写父类中的方法
            super.hi();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • final修饰的属性又称为常量,在定义时必须赋初值并且之后不能再修改(赋值在定义时,在构造器中,在代码块中)。

    • 如果修饰的属性是static的,只能在定义时和代码块中赋值

    • final不能继承,但是可以实例化对象。

    • final不能修饰构造器。

    • final和static搭配使用效率更高。

    final class B extends A{
        public final String name = "YYYY";
    
        {
            name = "YYYY";
        }
    
        public B(String name) {
            this.name = name;
        }
    }
    final class B extends A{
        public static final String name;
    
        static {
            name = "YYYY";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    六、抽象类

    父类的某些方法,需要声明但是又不确定如何实现,可以将其声明为抽象方法,这个类称为抽象类。(没有方法体的方法)

    当一个类中存在抽象方法时,需要将该类声明为抽象类。

    abstract class A{
        public abstract void fun();
    }
    
    • 1
    • 2
    • 3
    • 抽象类不能制造对象,但是可以有任意成员(非抽象方法,构造器,静态属性等)

    • 继承自抽象类的子类必须覆盖父类中的抽象函数(实现所有抽象方法),否则自己成为抽象类。

    • 两种抽象:与具体相对,表示一种概念而非实体;与细节相对,表示在一定程度上忽略细节而着眼大局。

    package Abstract;
    
    public class abstract02 {
        public static void main(String[] args) {
            B b = new B();
            b.calculateTime();
        }
    }
    
    abstract class A {
        public abstract void job1();
    
        public void calculateTime(){
            long start = System.currentTimeMillis();
            job1();
            long end = System.currentTimeMillis();
            System.out.println(end - start);
        }
    }
    
    class B extends A {
    
        public void job1() {
            int num = 0;
            for (int i = 1; i < 1000000; i++) {
                num *= i;
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    七、接口

    给出一些没有实现的方法,封装到一起,到某个类要使用的时候再根据具体情况把这些方法写出来。

    接口是纯抽象类,所有的成员函数都是抽象函数,所有的成员变量都是public static final。

    在jdk8.0之后,接口中可以有方法的具体实现(使用default关键字修饰或者静态方法)

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

    • 普通类实现接口,就必须将该接口的所有方法都实现,抽象类实现接口可以不用。

    • 一个类可以实现多个接口,接口中属性的访问形式接口名.属性名

    • 类可以实现很多接口,接口可以继承接口但是不能继承类.

    • interface A extends B,C{}

    package interface01;
    
    public interface interface01 {//修饰符 interface 接口名,修饰符只能是public和默认
    
        public void start();//属性、方法
        public void stop();
        
        default public void fun(){
            System.out.println("ok");
        }
    
        public static void fun1(){
            System.out.println("okk");
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    package interface01;
    
    public class int01 implements interface01{//修饰符 class 类名 implements 接口
        @Override
        public void start() {//实现接口的抽象方法
            System.out.println("01Strart");
        }
    
        @Override
        public void stop() {
            System.out.println("01Stop");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    package interface01;
    
    public class int03 {
        public void work(interface01 interface01){
            interface01.start();
            interface01.stop();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    package interface01;
    
    public class test {
        public static void main(String[] args) {
            int01 int01 = new int01();
            int03 int03 = new int03();
    
            int03.work(int01);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    面向接口的编程方式: 先定义接口再实现类,任何需要在函数间传入传出的一定是接口而不是具体的类。(代码量膨胀很快)

    实现接口与继承类: 实现接口是对java单继承机制的补充,继承用于解决代码的复用性和可维护性,接口在于设计各种规范让其他类去具体实现这些方法。接口比继承更加灵活,只需满足like-a的关系。

    接口类型的变量可以指向实现了该接口的类的对象实例。接口类型 名称 = new 实现了接口的类();

    接口多态传递: 如果一个接口1继承了接口2,而一个类实现了接口1,实际上这个类也实现了接口2。

    要明确指定的属性,访问接口就使用接口名.属性名访问父类的属性就使用super.属性名

    package interface02;
    
    interface A{
        int x = 1;
    }
    
    class B{
        int x = 1;
    }
    
    public class C extends B implements A{
    
        public void Px(){
            System.out.println(super.x);
            System.out.println(A.x);
        }
    
        public static void main(String[] args) {
            new C().Px();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
  • 相关阅读:
    用什么项目管理软件科学统筹“双11”
    常见排序方法原理及C语言实现
    四维轻云主要功能介绍
    python匿名函数和高阶函数总结
    2024 Q1:AVP时代下全球XR头显市场动态与展望
    跨境电商新手如何防止店铺关联?用什么工具好?
    平均负载与 CPU 使用率,到底有啥区别?
    目标检测性能评价指标
    Django数据库orm操作以list形式获取数据库中某列所有值
    嵌入式分享合集89
  • 原文地址:https://blog.csdn.net/qq_45902224/article/details/127979342