【Java面试题-基础知识02】Java抽象类和接口六连问?
1、抽象类和接口分别是什么?
- 抽象类是一种类,可以包含抽象方法和非抽象方法,抽象方法是没有具体实现的方法,需要在子类中被具体实现。
- 接口是一种完全抽象的类,其中的所有方法都是抽象方法,没有方法体,它只是定义了一组方法的契约。
2、接口中一定不可以有实现方法吗?
不一定,Java 8 引入了默认方法(Default Methods)的概念,允许在接口中包含具有默认实现的方法。
public interface MyInterface {
// 抽象方法
void abstractMethod(); // 默认方法
default void defaultMethod() {
System.out.println("This is a default method in MyInterface.");
}
}
3、抽象类和接口的使用场景?
- 抽象类适合于那些有一定相似功能的类,其中一些方法需要在子类中实现,而其他方法已经实现了一部分,可以被子类直接继承和复用。
// 抽象类 Animal
abstract class Animal {
private String name; public Animal(String name) {
this.name = name;
} // 抽象方法,需要在子类中实现
public abstract void makeSound(); // 具体方法,被子类继承和复用
public void eat() {
System.out.println(name + " is eating.");
}
} // 子类 Dog 继承自抽象类 Animal
class Dog extends Animal {
public Dog(String name) {
super(name);
} // 实现抽象方法
@Override
public void makeSound() {
System.out.println("Dog " + super.name + " barks.");
}
} // 子类 Cat 继承自抽象类 Animal
class Cat extends Animal {
public Cat(String name) {
super(name);
} // 实现抽象方法
@Override
public void makeSound() {
System.out.println("Cat " + super.name + " meows.");
}
} public class Main {
public static void main(String[] args) {
Dog dog = new Dog("Buddy");
dog.makeSound(); // Output: Dog Buddy barks.
dog.eat(); // Output: Buddy is eating. Cat cat = new Cat("Whiskers");
cat.makeSound(); // Output: Cat Whiskers meows.
cat.eat(); // Output: Whiskers is eating.
}
}
- 接口适合于定义类的行为,而不关心类的内部数据状态。如果多个不同类具有相同的行为,但是其内部实现不同,可以通过接口来实现这种行为的统一。
// 定义接口 Animal
interface Animal {
void makeSound();
} // 实现接口 Animal 的类 Dog
class Dog implements Animal {
@Override
public void makeSound() {
System.out.println("Dog barks.");
}
} // 实现接口 Animal 的类 Cat
class Cat implements Animal {
@Override
public void makeSound() {
System.out.println("Cat meows.");
}
} public class Main {
public static void main(String[] args) {
Animal dog = new Dog();
dog.makeSound(); // Output: Dog barks. Animal cat = new Cat();
cat.makeSound(); // Output: Cat meows.
}
}
4、抽象类可以直接实例化吗?
抽象类不能被直接实例化(不可以 Animal dog =new Animal()),在上面的示例中,抽象类 Animal
不能直接被实例化,但是可以创建其子类 Dog
和 Cat
的实例来使用:
Animal dog = new Dog("Buddy");
Animal cat = new Cat("Whiskers");
5、说一个使用抽象类实现的设计模式?
模板方法模式,代码如下:
// 步骤 1:创建一个抽象类,定义算法的骨架。
abstract class Beverage { // 模板方法,定义了算法的骨架
public final void prepareBeverage() {
boilWater();
brew();
pourInCup();
if (customerWantsCondiments()) {
addCondiments();
}
} // 具体步骤由子类实现
abstract void brew(); abstract void addCondiments(); // 公共步骤,已经实现
void boilWater() {
System.out.println("Boiling water");
} void pourInCup() {
System.out.println("Pouring into cup");
} // 钩子方法,子类可以覆盖它以提供特定实现
boolean customerWantsCondiments() {
return true;
}
} // 步骤 2:创建具体子类,实现抽象类中的抽象方法。
class Coffee extends Beverage { @Override
void brew() {
System.out.println("Dripping Coffee through filter");
} @Override
void addCondiments() {
System.out.println("Adding Sugar and Milk");
} // 通过重写钩子方法,可以选择不添加调料
@Override
boolean customerWantsCondiments() {
// 重写钩子方法,这里返回false表示不添加调料
return false;
}
} class Tea extends Beverage { @Override
void brew() {
System.out.println("Steeping the tea");
} @Override
void addCondiments() {
System.out.println("Adding Lemon");
}
} // 步骤 3:使用模板方法创建对象并调用其方法。
public class TemplatePatternDemo { public static void main(String[] args) {
Beverage coffee = new Coffee();
System.out.println("Making coffee...");
coffee.prepareBeverage(); System.out.println("\n"); Beverage tea = new Tea();
System.out.println("Making tea...");
tea.prepareBeverage();
}
}
6、说一个使用接口实现的设计模式?
策略模式,代码如下:
// 步骤 1:创建一个接口,定义算法的统一接口。
interface DiscountStrategy {
double applyDiscount(double originalPrice);
} // 步骤 2:创建具体策略类,实现接口中定义的算法。
class ChristmasDiscountStrategy implements DiscountStrategy {
@Override
public double applyDiscount(double originalPrice) {
return originalPrice * 0.8; // 圣诞节打八折
}
} class BlackFridayDiscountStrategy implements DiscountStrategy {
@Override
public double applyDiscount(double originalPrice) {
return originalPrice * 0.7; // 黑色星期五打七折
}
} // 步骤 3:创建使用策略的客户类。
class ShoppingCart {
private DiscountStrategy discountStrategy; public ShoppingCart(DiscountStrategy discountStrategy) {
this.discountStrategy = discountStrategy;
} public double checkout(double totalPrice) {
// 应用促销策略
double finalPrice = discountStrategy.applyDiscount(totalPrice);
System.out.println("Final price after discount: " + finalPrice);
return finalPrice;
}
} // 步骤 4:使用策略模式进行测试。
public class StrategyPatternDemo {
public static void main(String[] args) {
// 圣诞节促销
ShoppingCart christmasCart = new ShoppingCart(new ChristmasDiscountStrategy());
christmasCart.checkout(100); // 应付 80 System.out.println(); // 黑色星期五促销
ShoppingCart blackFridayCart = new ShoppingCart(new BlackFridayDiscountStrategy());
blackFridayCart.checkout(100); // 应付 70
}
}
【Java面试题-基础知识02】Java抽象类和接口六连问?的更多相关文章
- Java面试题-基础知识
参考文章:Java面试题-基础知识 基础能力 什么是值传递和引用传递 线程状态有哪些,它们之间是如何转换的 进程与线程的区别,进程间如何通讯,线程间如何通讯? HashMap的数据结构是什么?如何实现 ...
- java基础知识回顾之抽象类和接口的区别
/* 抽象类和接口的异同点: 相同点: 都是不断向上抽取而来的. 不同点: 1,抽象类需要被继承,而且只能单继承. 接口需要被实现,而且可以多实现. 2,抽象类中可以定义抽象方法和非抽象方法,子类继承 ...
- 漫漫Java路1—基础知识—初涉java
前言 主学信息安全,在编程的路上还是一个孩子,还在一步一步探索,有些东西可能是站在自己的位置思考的,很可能会出现一些啼笑皆非的错误,如果有误,还希望各位斧正. Java安装 jdk的安装 甲骨文官网选 ...
- Java面试题基础知识(收集)
1.集合类:list和Set比较,各自的子类比较(Arraylist,Vector,inkedLIst,HashSet,TreeSet) List:存入元素有序,元素可以重复,允许null值得存在,主 ...
- Java并发(基础知识)—— Java中断机制
上文讲解了Java线程的创建.启动以及停止,在讲到停止线程时说到了Java中断,Java中断是停止线程的一种协作机制,本文打算对Java中断机制进行详细讲解. 在网上搜索Java中断机制,发现两篇好文 ...
- 【JAVA】【基础知识】Java程序执行过程
1. Java程序制作过程 使用文本编辑器进行编辑 2. 编译源文件,生成class文件(字节码文件) javac源文件路径. 3.运行程序class文件.
- 【Java面试】基础知识篇
[Java面试]基础知识篇 Java基础知识总结,主要包括数据类型,string类,集合,线程,时间,正则,流,jdk5--8各个版本的新特性,等等.不足的地方,欢迎大家补充.源码分享见个人公告.Ja ...
- 020 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 14 变量与常量 知识总结
020 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 14 变量与常量 知识总结 本文知识点:变量与常量 知识总结 Java中的标识符 Java中的关键字 目前常 ...
- 第二十八节:Java基础-进阶继承,抽象类,接口
前言 Java基础-进阶继承,抽象类,接口 进阶继承 class Stu { int age = 1; } class Stuo extends Stu { int agee = 2; } class ...
- 094 01 Android 零基础入门 02 Java面向对象 02 Java封装 01 封装的实现 03 # 088 01 Android 零基础入门 02 Java面向对象 02 Java封装 02 static关键字 04 static关键字(续)
094 01 Android 零基础入门 02 Java面向对象 02 Java封装 01 封装的实现 03 # 088 01 Android 零基础入门 02 Java面向对象 02 Java封装 ...
随机推荐
- 使用Git向Gitee仓库推送项目的完整流程
1.安装git 如果没有特殊需求,直接下一步即可:安装链接如下:Git - Downloads (git-scm.com) 2.在Gitee上新建仓库,初始化仓库 3.保存仓库的链接,如下图标记所示 ...
- Python爬取网页遇到:selenium.common.exceptions.WebDriverException解决方法
在PyCharm中写好下列程序: 一运行遇到下列报错: selenium.common.exceptions.WebDriverException: Message: 'chromedriver' e ...
- Serverless Devs 2.0 全新发布,让 Serverless 应用开发更简单
简介: 2020 年 10 月 23日,阿里巴巴正式宣布开源其首个 Serverless 开发者平台 Serverless Devs.历经近一年精心打磨,今天 Serverless Devs 2.0 ...
- [Docker] 使 Volume 独立于容器运行时的方式 - 让容器引擎去处理
在单纯使用 run 命令运行一个容器时,通常会使用 -v 挂载的方式来实现宿主机数据卷映射到容器内. 使用命令: $ docker run --name mysql-con -v /my/custom ...
- dotnet 将任意时区的 DateTimeOffset 转换为中国时区时间文本
本文告诉大家在拿到任意时区的 DateTimeOffset 对象,将 DateTimeOffset 转换为使用中国的 +8 时区表示的时间 在开始之前,需要说明的是,采用 DateTimeOffset ...
- NetCore开发第一步 Log4Net日志引入
1.新建一个带mvc模板的项目: 2.引入Microsoft.Extensions.Logging.Log4Net.AspNetCore包,不要引入错了. 引入后后包的结果如下: 3.Startup类 ...
- 路由跳转报错:Uncaught (in promise) NavigationDuplicated {_name: "NavigationDuplicated", name: "NavigationDuplicated",...
记录一个路由跳转的报错: 将换成
- Oracle和达梦:获取表是否被锁定
1.获取表是否被锁定 select "V$SESSIONS".SESS_ID,"V$SESSIONS".SQL_TEXT,"V$SESSIONS&qu ...
- EasyRepro与测试自动化( 一) 概览
EasyRepro是一个框架,允许在特定的Dynamics 365组织上执行自动化UI测试.你可以使用它来自动化冒烟测试.回归测试和负载测试等.该框架是由开源项目Selenium构建的,Seleniu ...
- 16、数据库加固-mongo 加固
1.指定日志与数据库存放位置 在配置文件中设置指向目录位置 自建配置文件:vim /usr/local/mongodb/etc/mongodb.conf dbpath=/data/db logpath ...