当前位置: 首页 > news >正文

Java基础——抽象类与接口

前言:

在Java面向对象编程中,抽象类,接口,内部类以及Object类是构建灵活,可拓展代码的核心工具。理解它们的区别与联系,掌握使用场景,是每一位Java开发者进阶的必经之路。

本文将结合通俗易懂的案例,带你彻底搞懂:

抽象类的概念,语法和特性

接口的定义,多实现与继承

Object类的常用方法(toString,equals)

各种内部类的使用(静态内部类,实例内部类,局部内部类,匿名内部类)

抽象类与接口的核心区别

目录

前言:

一.抽象类

1.1为什么需要抽象类

1.2抽象类语法

1.3抽象类特性

1.4抽象类的作用

二.接口

2.1接口的概念

2.2接口语法

2.3接口的实现

2.4接口特性

2.5实现多个接口

2.6接口间的继承

2.7接口使用实例:对象比较

2.8Cloneable接口与深拷贝

三.抽象类VS接口

四.Object类

4.1toString()——获取对象信息

4.2equals()——对象比较

五.内部类

5.1静态内部类

5.2实例内部类(非静态)

5.3局部内部类

5.4匿名内部类

六,总结


一.抽象类

1.1为什么需要抽象类

在面向对象的世界里,所有对象都是通过类来描述的。但有些类并不具体,无法描述一个真实对象。比如:

Shape(图形)——它只是一个概念,无法画出具体的形状

Animal(动物)——它只是一个统称,无法让动物发出具体的叫声

这些类缺少足够的信息来描述对象,因此应该被设计为抽象类

抽象类就像一张设计图纸,不能直接拿来住人,但是可以知道建造具体的房子。

1.2抽象类语法

使用abstract关键字修饰列和方法:

public abstract class Shape{ //抽象方法;没有方法体,必须由子类实现 public abstract void draw(); //抽象类可以有自己的属性和普通方法 private double area; public double getArea(){ return area; } }

1.3抽象类特性

1.不能实例化:

Shape shape =new Shape(); //编译错误

2.抽象方法不能是private ,fianl,static

abstract private void test(); // 错误 abstract final void test2(); // 错误 abstract static void test3(); // 错误

3.子类必须重新给所有抽象方法,否则子类也必须声明为抽象类

public class Cricle extends Shape{ @Override public void draw (){ System.out.println("画一个圈"); } }

4.抽象类可以有构造方法,供子类调用初始化父类成员

5.抽象类不一定包含抽象方法,但抽象方法的类一定是抽象类

1.4抽象类的作用

抽象类存在的最大意义:多一层编译器的校验。

如果某个方法不应该由父类实现,而必须由子类实现,那么将其声明为抽象方法,父类声明为抽象类。这样一旦由人误用父类实例化,编译器立即就会报错,避免逻辑错误。

二.接口

2.1接口的概念

接口是一种公共的行为规范。只要符合规范,不同设备都可以通用。再Java中,接口是一种引用数据类型,是多个类的公共规范

2.2接口语法

public interface USB{ //接口中的变量默认是 public static final double VERSION =3.0 //方法默认是public abstract void openDevice(); }

2.3接口的实现

使用implements关键字,一个类可以实现多个接口。

public class Mouse implements USB { @Override public void openDevice() { System.out.println("打开鼠标"); } @Override public void closeDevice() { System.out.println("关闭鼠标"); } }

2.4接口特性

1.不能直接实例化

2.所有方法默认public abstract(Java 8后可以有default和static方法)

3.变量默认public static final

4.没有构造方法

5.一个类可以实现多个接口,弥补了单继承的不足

2.5实现多个接口

class Frog extends Animal implements IRunning, ISwimming { @Override public void run() { System.out.println(name + "正在跳"); } @Override public void swim() { System.out.println(name + "正在游泳"); } }

2.6接口间的继承

接口可以多继承,使用extends:

interface IAmphibious extends IRunning, ISwimming { }

这样IAmphibious就合并了IRunning和ISwimming两个接口的方法。

2.7接口使用实例:对象比较

方式一:实现Comparable接口

class Student implements Comparable<Student>{ private String name; private int score; @Override public int compareTo(Student o){ return this.score-o.score; } }

方式二:Comparator接口

class ScoreComparator implements Comparator<Student> { @Override public int compare(Student o1, Student o2) { return o1.score - o2.score; } }

2.8Cloneable接口与深拷贝

Cloneable是一个标记接口(没有任何方法),用于告诉JVM该类可以安全地克隆

class Person implements Cloneable { public Money money = new Money(); @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); // 浅拷贝 } }

浅拷贝:只拷贝对象本身,内部引用类型成员仍然指向同一个对象。

深拷贝:需要手动实现,拷贝递归所有类型成员

三.抽象类VS接口

对比项抽象类接口
关键字abstract classinterface
实例化不能不能
构造方法可以有不能有
不同方法可以有

Java8前不能,之后可以有

default/static方法

成员变量各种访问权限默认private static final
继承/实现单继承多实现
使用场景表示“是什么”表示“能做什么”

核心区别:抽象类可以包含普通方法和成员变量,子类可以直接复用;接口只定义规范,子类必须全部实现。

四.Object类

所有类都直接或间接继承Object,它是类层次结构的根

4.1toString()——获取对象信息

System.out.println(obj); // 默认调用 obj.toString()

默认实现:类名@哈希码的十六进制。通常需要重写以返回有意义的描述。

4.2equals()——对象比较

默认比较地址(和==一样)。若要比较内容,必须重写:

@Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null || getClass() != obj.getClass()) return false; Person person = (Person) obj; return age == person.age && Objects.equals(name, person.name); }

五.内部类

内部类是指定义在另一个内部的类。它也是一种封装形式。

5.1静态内部类

被static修饰,只能访问外部类的静态成员。

public class OutClass { static class InnerClass { public void method() { // 只能访问外部类的静态成员 } } } // 创建 OutClass.InnerClass inner = new OutClass.InnerClass();

5.2实例内部类(非静态)

可以访问外部类的任何成员。创建时需要先有外部类实例。

public class OutClass { class InnerClass { public void method() { // 可以直接访问外部类成员 } } } // 创建 OutClass out = new OutClass(); OutClass.InnerClass inner = out.new InnerClass();

5.3局部内部类

定义在方法内部,只能再方法内使用,不能使用访问修饰符。

public void method() { class LocalClass { // ... } LocalClass lc = new LocalClass(); }

5.4匿名内部类

没有名字,在创建的同时之间实现接口或继承类。常用于一次性使用的场景。

Greeting greeting = new Greeting() { @Override public void greet() { System.out.println("Hello!"); } }; greeting.greet();

匿名内部类可以访问外部类的成员,以及所在方法的final或effectively final的局部变量。

六,总结

抽象类:用来表示“一种类型”,可以有部分实现,子类通过继承复用代码。

接口:用来表示“能力/规范”,强调“能做什么”,实现类需要全部实现

Object类:所有类的父类,牢记toSring,equals的重写规则。

内部类:根据位置和修饰符分为四种,匿名内部类在GUI编程,事件监听中极为常用。

http://www.jsqmd.com/news/794361/

相关文章:

  • 谱域图算子与边缘计算优化实践
  • Java 判断选择循环
  • Agent Framework 中智能体的Concurrent编排模式
  • 《Java 100 天进阶之路》第1篇:编程语言类型有哪些?我心中的TOP1编程语言,什么是Java跨平台性?
  • JDBC实现数据库增删改查
  • Cursor智能体开发:Agent 模式
  • 把边界立起来,理解 ABAP Cloud 的几根主梁
  • LangChain详解
  • SpringBoot的服装商城系统毕设源码
  • Unity路网建模踩坑实录:OpenDRIVE解析中那些“反直觉”的几何参数(hdg, curvature到底怎么算?)
  • 渗透测试技巧(七)| 系统提权
  • 从 CDS 到服务契约,读懂 ABAP Cloud 的 Model-Driven Architecture
  • openwrt--by--myself
  • PyTorch 为什么现在要把 `Helion` 推到台前:它不是“又一个 Triton 替代品”,真正稀缺的是可移植 kernel authoring 这层
  • Java 开发问题:ArrayList 容量误解导致越界
  • 别再瞎学 C 语言了!真・胎教级入门教程 | NO.3 万字详解分支与循环 | 下篇
  • 从混淆矩阵到mIOU:手把手解析语义分割核心评价指标
  • Unity RenderTexture进阶:从刮刮乐到可擦写3D表面(Shader与LineRenderer实战)
  • 离线式SMPS输入整流器设计与优化指南
  • web项目工程搭建、Result封装类、部门功能的增删改查和日志技术Logback
  • ImageGlass深度解析:打造Windows平台高效图像浏览的实战指南
  • DISTINCT 带 WHERE 仍全表扫描?两层优化刀法拆解
  • 鸿蒙与 H5 通信使用的方法及原理
  • 如何彻底解决显卡驱动残留问题?Display Driver Uninstaller深度解析指南
  • 英伟达400亿投资帝国:从卖芯片到控生态,黄仁勋的AI全链路野心
  • PCI、PCIe与InfiniBand接口技术对比与应用解析
  • 百度网盘直链解析技术深度解析:突破限速壁垒的工程实践
  • 【测试方案_100 BASE-T1】快速掌握100BASE-T1 PMA物理层一致性测试
  • MySQL索引失效
  • MCP协议实战:outx-mcp-server如何安全扩展AI工具调用能力