面向对象进阶2

测试代码:
public class TestCeShi {
    public static void main(String[] args) {


        TestSon s1 = new TestSon();
    }
}

1. 静态 static

静态内部类、静态变量、静态常量(被static修饰过)

1.5 静态调用

定义静态变量、方法、内部类

public class StaticD {

    private String name;
    static int age;

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public static void fun(){
        System.out.println("guchao");
    }
    public void fun2(){
        System.out.println("wanglei");
    }

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

  测试类:

public class DiaoYong {
    public static void main(String[] args) {
        //静态方法调用
        StaticD.fun();

        //        静态变量调用
        StaticD.age = 15;

        //普通方法调用
        StaticD s1 = new StaticD();
        s1.fun2();

        //普通变量调用
        s1.setName("guchao");


    }
}

 2. 单例模式

要求程序中某一个组件,在程序运行的整个生命周期,只有一个实例

构造函数私有,外面的组件不可以主动创建这个对象

1.构造函数私有,外面的组件不能主动创建这个对象

2.提供静态方法返回对象实例,返回的是静态实例

2.1 饿汉式单例模式:

在类健在时就被创建,无论是否使用。

构造函数素有,防止其他地方直接创建实例

实现简单、线程安全、任何时候都能保证只有一个实例存在

缺点是加载时间长,如果这个类一直没有使用会造成资源浪费

public class LanHan {
    private LanHan() {
        System.out.println("实例化");
    }

    //静态初始化,发生的最早
    public static LanHan instance = new LanHan();

    public static LanHan getInstance(){
        return instance;
    }
}
饿汉式

先初始化加载instance,并实例化个对象 指向堆里的内存地址。然后加载类,并调用getInstance,创建s1,返回instance。

 2.2 懒汉式

没有静态初始化,等使用的时候在创建,实现了延迟加载,避免资源浪费 

需考虑线程安全问题,如果多线程同时调用获取实例方法,并且实例未创建,可能导致多次创建

public class EEEhanshi {

    private EEEhanshi() {
        System.out.println("懒汉式实例化");
    }

    private static EEEhanshi instance = null;

    public static EEEhanshi getInstance(){
        if (instance == null){  //如果为空,创建新的实例对象,否则不用添加
            instance = new EEEhanshi();
        }
        return instance;
    }
}
懒汉式
public class HungryTest {
    public static void main(String[] args) {

        Hungry s1 = Hungry.getInstance();
        Hungry s2 = Hungry.getInstance();
        Hungry s3 = Hungry.getInstance();
        Hungry s4 = Hungry.getInstance();

        EEEhanshi s5 = EEEhanshi.getInstance();
        EEEhanshi s6 = EEEhanshi.getInstance();
    }
}
测试类

3. 代码块和初始化顺序

插 : 初始化

变量的初始化,具体取决于变量的类型和声明位置。

1.声明时赋初值:在声明变量的同时为其赋初值

2.构造函数初始化:对于类的实例变量,在对象创建时使用构造函数为其赋值

3.静态变量初始化:可以在生命是或者静态初始化块中进行初始化

 

 4.默认初始化:如果没有显式初始化变量,则会进行默认初始化。数值类型的默认值为 0 或 0.0,布尔类型的默认值为 false,引用类型的默认值为 null。

java中,类的代码块分为静态(static block)和实例(instance block)代码块。

对象初始化顺序:

1.静态初始化

2.初始化

3.构造函数

4.父类先执行

3.1 案例

父类代码:
public class Test {

    int i = 0; //默认初始化
    {
        System.out.println("初始化代码块");
    }

    {
        System.out.println("初始化代码块2");
    }

    static int i2 = 0; //静态初始化
    static{
        System.out.println("静态初始化代码块");
    }
    static {
        System.out.println("静态初始化代码块2");
    }

    public Test() {

        System.out.println("父类初始化构造函数");
    }
}
子类代码
public class TestSon extends Test{

    int i = 0; //默认初始化
    {
        System.out.println("儿子初始化代码块");
    }

    {
        System.out.println("儿子初始化代码块2");
    }

    static int i2 = 0; //静态初始化
    static{
        System.out.println("儿子静态初始化代码块");
    }
    static {
        System.out.println("儿子静态初始化代码块2");
    }

    public TestSon() {

        System.out.println("子类初始化构造函数");
    }
}

 

 案例执行顺序:

1.父类的静态初始化代码块

2.子类的静态初始化代码块

3.父类的初始化代码块

4.父类的构造函数

5.子类的初始化代码块

6.子类的构造函数

 4. final关键词


public  class FinalDemo {
    
//    final  void f1(){}  //不能被重写
    void f1(){}
    
}
class b extends FinalDemo{  //只能有一个public
    //不能继承final类
    final int age = 35;

    @Override
    void f1() {
//        age = 36;  age不能被改变
        super.f1();
    }
}

修饰类:不能被继承

修饰方法:不能被重写

修饰变量:不能被改变

5. 抽象类

抽象类是一种不能被实例化的类,用于作为其他类的父类或基类,可以包含抽象方法和具体类,用于定义子类共有的属性和行为。

  1. 抽象类不能被实例化,只能作为其他类的父类来使用。
  2. 抽象类可以包含抽象方法和具体方法。
  3. 抽象方法是没有具体实现的方法,只有方法签名。子类必须实现抽象方法。
  4. 具体方法是有具体实现的方法,子类可以直接继承和使用。
  5. 子类继承抽象类时,如果不实现所有的抽象方法,那么子类也必须声明为抽象类。

5.1 案例

public abstract class Animal {
    private String name;

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

    // 抽象方法
    public abstract void makeSound();

    // 具体方法
    public void sleep() {
        System.out.println(name + " is sleeping.");
    }
}

在上述代码中Animal是一个抽象类,定义了一个私有的String变量name,创建了构造函数Animal

包含一个抽象方法makesound 并且还有一个具体方法sleep  子类继承此父类时必须实现抽象方法:

public class Dog extends Animal {
    public Dog(String name) {
        super(name);
    }

    @Override
    public void makeSound() {
        System.out.println("Dog is barking.");
    }
}

6. 接口

  • 一方面, 有时必须从几个类中派生出一个子类, 继承它们所有的属性和方法。 但是, Java不支持多重继承。 有了接口, 就可以得到多重继承的效果。
  • 接口就是规范,定义的是一组规则,体现了现实世界中“如果你是/要...则必须能...”的思想。 继承是一个"是不是"的关系,而接口实现则是 "能不能"的关系。
  • 接口的本质是契约,标准,规范,就像我们的法律一样。制定好后大家都要遵守。

案例:

public interface Usb {

    //接口的方法默认public abstract
    public abstract void start();

    void end();

    //接口中不能有普通方法
//    void f2() {
//    }

}


public interface TypeC {

    void transfer();

}


public class Printer implements Usb, TypeC {

    @Override
    public void start() {
        System.out.println("usb 启动");
    }

    @Override
    public void end() {
        System.out.println("usb 关闭");
    }

    public void transfer() {
        System.out.println("typeC接口传输数据");
    }
}

6.1 接口和抽象类的区别:

1.接口不能有具体方法

2.接口可以实现多继承,抽象类不可以

3.接口方法默认public anstract

7. 内部类和匿名内部类

7.1 内部类(Inner class)

java中可以把一个类放到另一个类的内部,这个类就是内部类,下边是几种类型:

1.成员内部类(Menber Inner Class):定义在外部类的成员位置,与外部类的实例相关联,

可以访问外部类的所有成员(包括私有成员)

7.1.1 案例:

public class Person {

    private String name;
    private int age;

    //内部类,如果一个类只给当前外部类使用,别的组件不用,比如Dog和Cat类只是在Person中使用
    //所有的成员变量的修饰符,都可以修饰内部类
    public static class Dog {

        public void eat() {
            System.out.println("狗吃骨头");
        }
    }

    public class Cat {

        public void eat() {
            System.out.println("猫吃鱼");
        }

    }

    public void f1() {
        class Bird {
            public void eat() {
                System.out.println("鸟吃虫子");
            }
        }
        Bird b = new Bird();
        b.eat();
    }

}



//测试类:

public class Test {

    public static void main(String[] args) {
        //创建静态成员内部类的方法
        Person.Dog dog = new Person.Dog();
        dog.eat();

        //创建非静态成员内部类的方法
        Person p = new Person();
        Person.Cat cat = p.new Cat();
        cat.eat();

        p.f1();

    }
}

7.2 匿名内部类(Anonymous Inner Class)

没有显式定义类的名称,而是通过new关键字来创建对象并覆盖

特点:

匿名内部类必须实现父类或实现接口 

匿名内部类只能有一个对象

匿名内部类只能使用多态形式引用

 

语法:

 7.2.1 案例

public class Test {

    public static void f1(Usb usb) {
        usb.start();
        usb.end();
    }

    public static void f2(TypeC typeC) {
        typeC.transfer();
    }

    public static void main(String[] args) {
//        //内部类
//        class Test$1 implements Usb {
//            @Override
//            public void start() {
//                System.out.println("打印机usb启动");
//            }
//
//            @Override
//            public void end() {
//                System.out.println("打印机usb停止");
//            }
//        }
//        Test$1 usb1 = new Test$1();

        //方式1
        /**
         * 1:多态性:编译类型是父类
         * 2:new 接口(类),后面跟一个实现
         * 3:有一个对象usb1,实现了Usb接口的一个没有名字的类的实例
         *
         * Test$1->实现了Usb接口->用这个类产生一个对象usb1
         */
        Usb usb1 = new Usb() {
            @Override
            public void start() {
                System.out.println("打印机usb启动");
            }

            @Override
            public void end() {
                System.out.println("打印机usb停止");
            }
        };
        f1(usb1);


        //方式2:匿名内部类直接作为方法参数
        f2(new TypeC() {
            @Override
            public void transfer() {
                System.out.println("苹果14 正在传输数据....");
            }
        });

    }



}

两种方法: 

1.匿名内部类 创建对象并 加一个实现 Usb usb1 = new Usb { 实现Usb的抽象方法和抽象类}

后边用f1调用usb1对象。
2.匿名内部类直接作为方法参数 f2(new TypeC){ 实现TypeC的抽象方法}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

王_垒

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

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

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

打赏作者

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

抵扣说明:

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

余额充值