Java基础题的复习----第三章

题目 


1.什么时候用instanceof(在项目中,或学过的框架源码,举例)
2.动态绑定,静态绑定
3.多态内存
4.为什么要有多态,解决了什么问题
5.接口和抽象类的异同  
6.什么时候使用接口,什么时候使用抽象类
7.什么是面向接口编程 
8.工厂模式,适配器各三种什么情况下使用找到框架中的使用源代码段
9.关键字:权限修饰符,static,abstract ,final能否修饰的内容:类,属性,方法,构造方法 


1.什么时候用instanceof(在项目中,或学过的框架源码,举例)

   instanceof 关键字在 Java 中用于检查一个对象是否是特定类或其子类的实例。这在处理多态对象时特别有用,尤其是在框架源码和实际项目中。

示例:
项目中使用 instanceof:

public void processShape(Shape shape) {
    if (shape instanceof Circle) {
        Circle circle = (Circle) shape;
        System.out.println("Circle area: " + circle.area());
    } else if (shape instanceof Rectangle) {
        Rectangle rectangle = (Rectangle) shape;
        System.out.println("Rectangle area: " + rectangle.area());
    } else {
        System.out.println("Unknown shape");
    }
}

框架源码中使用 instanceof:

在 Spring 框架中,instanceof 被频繁用于判断 bean 的类型。

if (bean instanceof InitializingBean) {
    try {
        ((InitializingBean) bean).afterPropertiesSet();
    } catch (Throwable ex) {
        throw new BeanCreationException(beanName, "Initialization of bean failed", ex);
    }
}

2. 动态绑定,静态绑定

1.静态绑定:  静态绑定发生在编译时,方法或属性调用在编译阶段就已经确定。主要适用于静态方法、私有方法和所有的字段。

public class StaticBinding {
    private void display() {
        System.out.println("Static binding in Java");
    }

    public static void main(String[] args) {
        StaticBinding obj = new StaticBinding();
        obj.display();
    }
}

2.动态绑定:动态绑定发生在运行时。Java 通过虚拟方法表(vtable)实现动态绑定,使得父类引用可以指向子类对象,并在运行时调用实际的子类方法。

class Parent {
    void show() {
        System.out.println("Parent's show()");
    }
}

class Child extends Parent {
    void show() {
        System.out.println("Child's show()");
    }
}

public class DynamicBinding {
    public static void main(String[] args) {
        Parent obj = new Child();
        obj.show();  // 动态绑定,调用的是子类的 show() 方法
    }
}

3. 多态内存

多态通过父类引用指向子类对象的方式实现。其内存布局如下:

1.对象头:存储对象的元数据,如对象的类型信息、GC 信息等。
2.实例数据:存储对象的成员变量。
3.方法区:存储类的信息,包括方法表(vtable),方法表指向实际的方法实现。


4. 为什么要有多态,解决了什么问题


多态允许对象在不同上下文中表现出不同的行为。它解决了以下问题:

1.代码重用:通过多态,可以编写更通用和可重用的代码。
2.灵活性和可扩展性:增加新的子类不需要修改现有代码,增强了系统的灵活性和可扩展性。
3.简化代码:通过统一接口调用不同实现,简化了代码结构。


5. 接口和抽象类的异同

相同点:

1.都不能实例化。
2.都可以包含抽象方法,供子类实现。
不同点:

接口:
只能包含抽象方法(Java 8 之后可以包含默认方法和静态方法)。
不可以包含实例变量。
类可以实现多个接口。
抽象类:
可以包含抽象方法和具体方法。
可以包含实例变量。
只能被单继承。

 

6. 什么时候使用接口,什么时候使用抽象类

使用接口:

当需要表示某种能力或行为时(如 Runnable 表示可运行的)。
当需要多个类实现共同的行为,但没有共同的父类时。

使用抽象类:

当有一组相关的类,且这些类共享某些方法或状态时。
当需要定义公共的行为并提供部分实现时。


7. 什么是面向接口编程

概述
  面向接口编程是一种软件设计原则,强调使用接口而不是具体实现类来定义程序组件的行为。其核心思想是依赖于抽象,而不是依赖于具体,实现模块之间的松耦合。这种方法使得代码更灵活、更容易维护和扩展。

优点
1.松耦合:模块之间的依赖性降低,改变一个模块时对其他模块的影响较小。高内聚,松耦合。
2.灵活性:通过接口,程序可以更容易地引入新功能或替换现有实现,而不需要修改调用者代码。
3.可测试性:容易为代码编写单元测试,可以通过接口轻松创建模拟对象(mock objects)。
4.可扩展性:通过实现接口,程序可以在不修改现有代码的情况下扩展新功能。
 

示例
以下是一个简单的面向接口编程的示例,展示如何使用接口定义行为,并通过不同的实现类实现这些行为。

接口定义:

public interface PaymentProcessor {
    void processPayment(double amount);
}


实现类:

public class CreditCardProcessor implements PaymentProcessor {
    @Override
    public void processPayment(double amount) {
        System.out.println("Processing credit card payment of $" + amount);
    }
}

public class PayPalProcessor implements PaymentProcessor {
    @Override
    public void processPayment(double amount) {
        System.out.println("Processing PayPal payment of $" + amount);
    }
}

8. 工厂模式,适配器模式

工厂模式(Factory Pattern)
定义:工厂模式是一种创建型设计模式,通过定义一个创建对象的接口,让子类决定实例化哪一个类。工厂模式使得一个类的实例化延迟到其子类。

优点
解耦:将对象的创建与使用分离,使得代码更加灵活和可维护。
可扩展性:通过添加新的子类,可以方便地引入新的产品,而不影响现有代码。
示例
假设我们需要创建不同类型的车辆,如汽车和卡车。

1. 定义车辆接口

public interface Vehicle {
    void drive();
}

2. 实现具体的车辆类


public class Car implements Vehicle {
    @Override
    public void drive() {
        System.out.println("Driving a car");
    }
}

public class Truck implements Vehicle {
    @Override
    public void drive() {
        System.out.println("Driving a truck");
    }
}

3. 创建工厂类

public class VehicleFactory {
    public Vehicle createVehicle(String type) {
        if (type.equalsIgnoreCase("car")) {
            return new Car();
        } else if (type.equalsIgnoreCase("truck")) {
            return new Truck();
        }
        return null;
    }
}

4. 使用工厂创建对象

public class Main {
    public static void main(String[] args) {
        VehicleFactory factory = new VehicleFactory();
        
        Vehicle car = factory.createVehicle("car");
        car.drive();
        
        Vehicle truck = factory.createVehicle("truck");
        truck.drive();
    }
}

适配器模式(Adapter Pattern)
定义:
适配器模式是一种结构型设计模式,用于将一个类的接口转换成另一个接口,以便原本接口不兼容的类可以一起工作。

目的:使得现有的类可以与其他接口兼容,提升系统的复用性和灵活性。

示例
假设我们有一个旧的音频播放器接口(MediaPlayer)和一个新的高级音频播放器接口(AdvancedMediaPlayer)。我们希望旧的播放器能够播放新格式的文件。

1. 定义旧的播放器接口

public interface MediaPlayer {
    void play(String audioType, String fileName);
}


2. 实现旧的播放器类

public class AudioPlayer implements MediaPlayer {
    @Override
    public void play(String audioType, String fileName) {
        if (audioType.equalsIgnoreCase("mp3")) {
            System.out.println("Playing mp3 file: " + fileName);
        } else {
            System.out.println("Invalid media. " + audioType + " format not supported");
        }
    }
}


3. 定义新的高级播放器接口

public interface AdvancedMediaPlayer {
    void playVlc(String fileName);
    void playMp4(String fileName);
}


4. 实现新的高级播放器类

public class VlcPlayer implements AdvancedMediaPlayer {
    @Override
    public void playVlc(String fileName) {
        System.out.println("Playing vlc file: " + fileName);
    }

    @Override
    public void playMp4(String fileName) {
        // Do nothing
    }
}

public class Mp4Player implements AdvancedMediaPlayer {
    @Override
    public void playVlc(String fileName) {
        // Do nothing
    }

    @Override
    public void playMp4(String fileName) {
        System.out.println("Playing mp4 file: " + fileName);
    }
}


5. 创建适配器类

public class MediaAdapter implements MediaPlayer {
    AdvancedMediaPlayer advancedMusicPlayer;

    public MediaAdapter(String audioType) {
        if (audioType.equalsIgnoreCase("vlc")) {
            advancedMusicPlayer = new VlcPlayer();
        } else if (audioType.equalsIgnoreCase("mp4")) {
            advancedMusicPlayer = new Mp4Player();
        }
    }

    @Override
    public void play(String audioType, String fileName) {
        if (audioType.equalsIgnoreCase("vlc")) {
            advancedMusicPlayer.playVlc(fileName);
        } else if (audioType.equalsIgnoreCase("mp4")) {
            advancedMusicPlayer.playMp4(fileName);
        }
    }
}


6. 更新旧的播放器类以使用适配器

public class AudioPlayer implements MediaPlayer {
    MediaAdapter mediaAdapter;

    @Override
    public void play(String audioType, String fileName) {
        if (audioType.equalsIgnoreCase("mp3")) {
            System.out.println("Playing mp3 file: " + fileName);
        } else if (audioType.equalsIgnoreCase("vlc") || audioType.equalsIgnoreCase("mp4")) {
            mediaAdapter = new MediaAdapter(audioType);
            mediaAdapter.play(audioType, fileName);
        } else {
            System.out.println("Invalid media. " + audioType + " format not supported");
        }
    }
}


7. 使用播放器

public class Main {
    public static void main(String[] args) {
        AudioPlayer audioPlayer = new AudioPlayer();
        
        audioPlayer.play("mp3", "song.mp3");
        audioPlayer.play("mp4", "movie.mp4");
        audioPlayer.play("vlc", "video.vlc");
        audioPlayer.play("avi", "my_movie.avi"); // Unsupported format
    }
}


9. 关键字:权限修饰符,static,abstract ,final能否修饰的内容:类,属性,方法,构造方法

修饰符属性方法  构造方法
public可以可以可以可以
protected不可以可以可以可以
private 不可以可以可以可以
static可以(内部类)可以可以不可以
abstract 可以不可以可以不可以
final可以可以可以不可以
  • 18
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值