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

学习笔记——《Java面向对象程序设计》-抽象和接口

参考教材:

Java面向对象程序设计(第3版)微课视频版 清华大学出版社

抽象方法

抽象方法是使用abstract关键字修饰的成员方法,抽象方法在定义时不需要实现方法体。

抽象方法的定义格式如下:

abstract void 方法名称(参数);

当一个类包含了抽象方法,该类必须是抽象类。抽象类和抽象方法一样,必须使用abstract关键字进行修饰。 不允许使用final和abstract同时修饰一个方法或类。

抽象类

抽象类的定义规则如下:

(1)包含一个以上抽象方法的类必须是抽象类。

(2)抽象类和抽象方法都要使用abstract关键字声明。

(3)抽象方法只需声明而不需要实现;abstract类不能用new运算符创建对象。

(4)如果一个非abstract类继承了抽象类,必须重写父类的abstract方法,即去掉abstract方法的abstract修饰,并给出方法体。

(5)如果一个abstract类继承了抽象类,也可以继承父类的方法。

// 定义抽象类Animal
abstract class Animal { 
// 定义抽象方法shout()abstract void shout(); 
}
// 定义Dog类继承抽象类Animal
class Dog extends Animal {
// 实现抽象方法shout()void shout() {System.out.println("汪汪...");}
}public class Example10 {public static void main(String[] args) {Dog dog = new Dog(); 	// 创建Dog类的实例对象dog.shout(); 		// 调用dog对象的shout()方法}
}

注意:使用abstract关键字修饰的抽象方法不能使用private修饰,因为抽象方法必须被子类实现,如果使用了private声明,则子类无法实现该方法。

abstract类的对象作为上转型对象

抽象类可以抽象出重要的行为标准,该行为用抽象方法来表示。即抽象类封装了子类必需有的行为标准。

抽象类声明的对象可以作为其子类的对象的上转型对象,调用子类重写的方法,即体现子类根据抽象类里的行为标准给出的具体行为。

//抽象类定义女友行为标准
abstract class GirlFriend { abstract void speak(); abstract void cooking(); 
}//中国女友具体实现
class ChinaGirlFriend extends GirlFriend {void speak() {System.out.println("你好"); // 中文问候}void cooking() {System.out.println("水煮鱼"); // 中式菜品}
}//美国女友具体实现
class AmericanGirlFriend extends GirlFriend {void speak() {System.out.println("hello"); // 英文问候}void cooking() {System.out.println("roast beef"); // 西式菜品}
}class Boy {GirlFriend friend;	//抽象类声明friend对象void setGirlfriend(GirlFriend f) {friend = f; }void showGirlFriend() {friend.speak();   friend.cooking(); }
}public class Example5_11 {public static void main(String args[]) {//抽象类声明的对象girl,成为子类ChinaGirlFriend的对象的上转型对象GirlFriend girl = new ChinaGirlFriend();//girl就可以调用子类中的重写方法Boy boy = new Boy();  // 设置中国女友并展示行为boy.setGirlfriend(girl);boy.showGirlFriend();// 切换为美国女友的上转型对象girl = new AmericanGirlFriend();boy.setGirlfriend(girl);boy.showGirlFriend();}
}

接口

Java不支持多继承,即一个类只能有一个父类。单继承性使得java简单,易于管理程序。为了克服单继承的缺点,Java使用了接口,一个类可以实现多个接口。

1、接口的定义

使用关键字interface来定义一个接口。接口的定义和类的定义很相似。分为接口声明和接口体。

interface Com{... 
}

(1)接口体中的抽象方法和常量

interface Printable{public static final int MAX = 100;	//等价于 int MAX = 100;public abstract void add();			//等价于 void add();public abstract float sum(float x,float y);	//等价于 float sum(float x,float y);
}

接口里不会有变量

(2)接口里可以定义抽象方法,但是不能有方法体;

(3)Java8之后,接口体中的default实例方法,default方法一定是public方法(public可省略)

interface Printable{public static final int MAX = 100;	//等价于 int MAX = 100;public abstract void add();			//等价于 void add();public abstract float sum(float x,float y);	//等价于 float sum(float x,float y);default int max(int a,int b) {return a+b;}
}

(4)接口中的static方法,允许再接口体中定义static方法

static和default不能同时修饰一个方法;

static和abstract也不能同时修饰一个方法;

interface Printable{public static final int MAX = 100;	//等价于 int MAX = 100;public abstract void add();			//等价于 void add();public abstract float sum(float x,float y);	//等价于 float sum(float x,float y);default int max(int a,int b) {return a+b;}public static void f() {System.out.println("注意是从Java SE 8开始的");}
}

2、接口的使用

(1)可以用接口名访问接口的常量、调用接口中的static方法

  (2)类实现接口

类通过使用关键字implements声明自己实现一个或多个接口

修饰符 class 类名 implements 接口1,接口2,...{...
}

一个类实现了某个接口,那么这个类就自然拥有了接口中的常量;

该类也可以重写接口中的default方法(注意,重写时需要去掉default关键字),但不自然拥有接口里的static方法

一个非abstract类实现了某个接口,那么这个类就必须重写该接口的所有abstract方法,去掉abstract修饰,并给出方法体;

一个abstract类实现了某个接口,该类可以重写接口的abstract方法,或直接拥有接口的abstract方法

要注意的是:接口中的方法的访问权限都是public的,重写时不可省略public

// 定义接口Animal
interface Animal {int ID = 1;                 // 定义全局常量String NAME = "牧羊犬";void shout();             // 定义抽象方法shout()static int getID(){      // 定义静态方法getID()return Animal.ID;
}public abstract void info();     // 定义抽象方法  	
}
// 定义接口Action
interface Action {public void eat();          // 定义抽象方法eat()
}
// 定义Dog类实现Animal接口和Action接口
class Dog implements Animal,Action{
// 重写Action接口中的抽象方法eat()public void eat() {System.out.println("喜欢吃骨头");}
// 重写Animal接口中的抽象方法shout()public void shout() {System.out.println("汪汪...");}
// 重写Animal接口中的抽象方法info()public void info() {System.out.println("名称:"+NAME);}
}
// 定义测试类
class Example11 {
public static void main(String[] args) {System.out.println("编号"+Animal.getID());Dog dog = new Dog();         // 创建Dog类的实例对象dog.info();dog.shout();                // 调用Dog类中重写的shout()方法dog.eat();                    // 调用Dog类中重写的eat()方法}}

(3)如果在开发中一个子类既要实现接口又要继承抽象类,则可以按照以下格式定义子类。

修饰符class 类名 extends 父类名implements 接口1,接口2,... {...
}

在Java中,接口是不允许继承抽象类的,但是允许一个接口继承多个接口。

abstract类与接口的比较 

(1)abstract类和接口都可以有abstract方法

(2)接口中只可以有常量,不能有变量;而abstract类中即可以有常量也可以有变量

(3)abstract类中也可以非abstract方法,但不可以有default实例方法。接口不可以有非abstract的方法(不是default方法,还带有方法体的方法),但可以有default实例方法。

http://www.xdnf.cn/news/1312.html

相关文章:

  • 实验1python基本网络应用
  • 为TA开发人员介绍具有最新改进的Kinibi-610a
  • 【Vue3 / TypeScript】 项目兼容低版本浏览器的全面指南
  • 【MySQL】数据库基础
  • 从马拉松到格斗大赛:人形机器人撕开的万亿市场,正在改写AI规则
  • STM32单片机入门学习——第45节: [13-2] 修改频主睡眠模式停止模式待机模式
  • G1 人形机器人硬件构成与接口
  • 图像挖掘课程笔记-第一章:了解机器视觉
  • 【TeamFlow】4.3.2 细化时间单位
  • 设备预测性维护系统部署成本:技术架构与成本优化策略解析
  • Linux——基于socket编程实现简单的Tcp通信
  • Size of map written was 1, but number of entries written was 0. 异常分析
  • 进阶篇 第 7 篇 (终章):融会贯通 - 多变量、模型选择与未来之路
  • 数据可视化--数据探索性分析
  • 数据库MySQL学习——day1(创建表与数据类型)
  • win10中打开python的交互模式
  • Ubuntu 22.04安装IGH
  • CRM系统的功能有哪些?CRM系统功能指南
  • RenderDoc 使用介绍
  • STL C++详解——priority_queue的使用和模拟实现 堆的使用
  • 高新技术申报有哪些潜在风险?如何避免?
  • AI 模型可靠性危机:DeepSeek 输出异常的技术归因与防范实践
  • 算力网络有关论文自用笔记(2)
  • L1-5、Prompt 写作中的常见误区
  • 公路路面病害检测
  • 【AI】SpringAI 第五弹:接入千帆大模型
  • 通过AI工具或模型创建PPT的不同方式详解,结合 Assistants API、DALL·E 3 等工具的功能对比及表格总结
  • 用红黑树封装出set和map
  • Pandas与NumPy高效结合使用指南
  • 利用内联注解析释差异构造多语言sql注入 -- b01lers CTF defense-in-depth