Java——面向对象(四)

static的运用——单例模式

定义: 对某个类只能存在一个对象实例
分类: 饿汉式、懒汉式
一般步骤:

  1. 构造器私有化→防止直接new
  2. 类的内部创建对象
  3. 向外暴露实例的一个静态方法
//饿汉式
class Bank{
    //1.私有化类的构造器
    private Bank( ){}
    //2.内部创建类的对象
    //4.要求此对象也必须声明为静态的
    private static Bank instance = new Bank( );
    //3.提供公共的静态的方法,返回类的对象
    public static Bank getInstance(){
        return instance;
    }
}
//懒汉式
class Order{
     //1.私有化类的构造器
     private Order(){}
     //2.声明当前类对象,没有初始化//4.此对象也必须声明为static的
     private static Order instance=null;
     // 3.声明public、 static的返回当前类对象的方法
     public static Order getInstance(){
         if(instance==null){
         instance=new Order();
     }
         return instance;
     }
}

饿汉式和懒汉式的区别

  1. 创建对象的时机不同,饿汉式在类加载时创建,懒汉式在使用时加载。
  2. 饿汉式不存在线程安全问题,懒汉式存在线程安全问题
  3. 饿汉式可能存在浪费资源的可能

类成员——代码块

作用:用来初始化类、对象
结构:【修饰符】{代码}
特点:

  1. 不能通过对象或类显示调用,而是在加载类或创建对象时隐式调用
  2. 如果加了static,则属于静态代码块,静态代码块随着类的加载而执行,并且只执行一次,而普通代码块每创建一个对象都会执行
  3. 如果只是使用类的静态成员,普通代码块并不会执行
    分类:静态代码块和非静态代码块(根据是否有static修饰)
  4. 静态代码块的使用
    1. 内部可以有输出语句
    2. 随着类的加载而执行,而且只执行一次
    3. 作用:初始化类的信息
    4. 如果一个类中定义了多个静态代码块,则按照声明的先后顺序执行
    5. 静态代码块的执行要优先于非静态
  5. 非静态代码块的使用
    1. 内部可以有输出语句
    2. 随着对象的创建而执行
    3. 每创建一个对象,就执行一次非静态代码块
    4. 作用:可以在创建对象时,对对象的属性等进行初始化

内部类

在Java中我们可以将类A声明在另一个类B中,这时类A被称为内部类,类B称为外部类。
分类:

  1. 定义在外部类的局部位置上
    1. 局部内部类
      1. 局部内部类使用和局部变量类似,不能加修饰符,可以使用final。
      2. 可以访问外部类的所有成员(包括私有的)
      3. 外部类访问:需要创建内部类的对象
    2. 匿名内部类
  2. 定义在外部类的成员位置上
    1. 成员内部类
      成员内部类一方面,作为外部类的成员:
        调用外部类的结构>可以被static修饰>可以被4种不同的权限修饰
      另一方面,作为一个类:
        类内可以定义属性、方法、构造器等;可以被final修饰,表示此类不能被继承。所以不使用final,就可以被继承;可以被abstract修饰。
    2. 静态内部类(使用static修饰)
public class Main{
    public static void main(String[] args) {
        Person1 p=new Person1();
        Person1.Man man=p.new Man();//针对非静态内部类的实例化方式。
        Person1.Women women=new Person1.Women();//静态内部类的实例化方式

        man.show();//内部类方法的调用
        women.show();//内部类方法的调用
    }

}
class Person1 {
    String name="1";
    int age;
    class Man{
        String name="2";
        int age;
        public void show(){
            System.out.println(name);//输出2,调用内部类的属性
            System.out.println(this.name);//输出2,调用内部类的属性
            System.out.println(Person1.this.name);//输出1,调用外部类的属性
        }
    }
    static class Women{
        String name="3";
        int age;
        public void show(){
            System.out.println(name);//输出3,调用内部类的属性
            System.out.println(this.name);//输出3,调用内部类的属性
            //System.out.println(Person1.this.name);这个会编译报错java: 无法从静态上下文中引用非静态 变量 this
        }
    }
}

抽象类

定义:当父类的某些方法,需要声明,但又不确定如何实现时,可以声明为抽象方法,对应的类是抽象类

特点:

  1. 抽象类不可实例化
  2. 一个类中只要有抽象方法,则必须声明为抽象类
  3. 抽象方法不可以有主体
  4. 继承抽象类的子类必须实现抽象类中的所有抽象方法。 (除非子类也是抽象类)
  5. 抽象方法不可用private、final和static修饰

接口(interface)

为什么要有接口?

对Java单继承机制的补充

与抽象类的区别

  1. 接口中的所有方法都没有方法体(JDK 7)
  2. 接口中可以有静态方法和默认方法(JDK 8)

特点

  1. 接口不可以实例化
  2. 接口中所有方法都是public,抽象方法可以省略关键字abstract
  3. 普通类实现接口,必须实现所有方法,抽象类可以不实现
  4. 一个类可以实现多个接口
  5. 接口中的属性,只能是final. 也就是必须初始化
  6. 接口属性访问方式:接口名.属性名
  7. 接口不可以继承其他类,但可以继承多个别的接口。 (接口只 能说继承另一个接口,不能说实现另一个接口)
  8. 接口存在“多态传递”现象
// 多态与多态传递
// 有接口A和B   B extends A     类 T  implements  B
B b=new T();  // 体现多态
A a=new T(); // 体现多态传递

定义接口

因为接口和类是并列的结构,所以定义方式类似。不过因为JDK7.0的更新,使得接口不止能够定义全局变量和抽象方法,还可以定义静态方法和默认方法。

全局变量格式:(public static final)类型 变量名 = 赋值 括号内的在书写时可以省略。

抽象方法格式:public abstract 方法名(){方法体}

使用事项:

  1. 接口中不可以定义构造器,也就意味着接口不可以被实例化
  2. Java开发中,接口通过让类去实现(implements)的方式来使用
      如果实现类覆盖了接口中的所有抽象方法,则此实现类就可以实例化
      如果实现类没有覆盖接口中所有的抽象方法,则此实现类仍为一个抽象类
  3. Java中一个类可以实现多个接口,这弥补了Java单继承的缺陷。
  4. 接口与接口之间可以继承,而且可以多继承。
  5. 接口的使用,体现了Java特性的多态性。
package com.psx;

/**
 * @author psx
 * @date 2021/2/1 9:18
 */
public class Main {
    public static void main(String[] args) {
        Person1 p=new Person1();
        p.eat();
        p.talk();
        Dog.show();
		System.out.println(Dog.a);
    }

}
class Person1 implements Dog{
    String name="1";
    int age;

    @Override
    public void eat() {
        System.out.println("吃饭了");
    }

}
interface Dog{
    public static final int a = 10;			//全局变量
    public abstract void eat();				//抽象方法
    public default void talk(){				//默认方法
        System.out.println("汪汪汪");
    }
    public static void show(){				//静态方法
        System.out.println("这是一只狗");
    }
}
public class Main{
    public static void main(String[] args) {
        Ball ball=new Ball("paiqiu");
        ball.play();
    }
}
interface Playable {
    void play();
}
interface Bounceable {
    void play();
}
interface Rollable extends Playable,Bounceable {
    Ball ball = new Ball( "PingPang" );
}
class Ball implements Rollable {
    private String name;

    public String getName() {
        return name;
    }
    public Ball(String name) {
        this.name = name;
    }
    public void play() {
        ball = new Ball("Football");//运行报错,ball在Rollable 接口中
        							///已经成为final属性了
        System.out.println(ball.getName());
    }
}

interface A {
    int x= 0;
}
class B {
    int x = 1;
}
class c extends B implements A {
    public void pX() {
        //System.out.println(x) ;报错,x指代不明确
        System.out.println(super.x);//调用父类的属性
        System.out.println(A.x);//调用接口的属性
    }
    public static void main(String[]args) {
        new c().pX();
    }
}

类变量

定义:定义在类中的静态变量

特点:

  1. 该变量被该类的所有实例共享
  2. 类加载时就生成了,随类消亡而销毁

类方法

实质就是静态方法。一般用于工具类中

特点:

  1. 类方法和普通方法一样随类的加载而加载。(注:类方法没有this
  2. 类方法可以通过类名或对象名调用
  3. 类方法只能访问静态变量或静态方法

类加载的时机

  1. 创建对象实例时(new)
  2. 创建子类对象实例时,对应的父类也会加载
  3. 使用类的静态成员时

创建对象时的调用顺序

  1. 静态代码块、静态属性初始化 (两者优先级相同)
  2. 普通代码块、普通属性的初始化
  3. 构造方法

创建子类对象时的调用顺序

  1. 父类静态代码块、静态属性
  2. 子类静态代码块、静态属性
  3. 父类普通代码块、普通属性
  4. 父类构造器
  5. 子类普通代码块、普通属性
  6. 子类构造器
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

菜菜的小彭

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

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

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

打赏作者

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

抵扣说明:

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

余额充值