覆写

继承性中的覆写与覆盖
本文详细介绍了在面向对象编程中,子类如何通过覆写父类的方法来实现功能扩展,以及属性覆盖的概念和作用。同时对比了覆写与重载之间的区别,并通过示例代码说明了覆写的具体实现。

继承性的主要特征是子类可以根据父类已有的功能进行功能的扩展,但是在子类定义属性或方法的时候,有可能定义的属性和方法与父类同名,这样的情况下就称为覆写。


一、方法的覆写

当子类定义了与父类方法名称相同、参数的类型及个数、返回值相同的方法时,就称为发生了覆写。

范例:观察覆写的产生效果

class A {
	public void fun() {
		System.out.println("A类中的fun()");
	}
}

class B extends A {

}

public class TestDemo {
	public static void main(String args[]) {
		B b = new B();
		b.fun();
	}
}

因为这个时候子类并没有fun()方法,所以这个时候子类使用fun()方法时,会直接使用A类继承而来的fun()方法。

范例:观察覆写

class A {
	public void fun() {
		System.out.println("A类中的fun()");
	}
}

class B extends A {
	public void fun() {// 此处为覆写
		System.out.println("B类中的fun()");
	}
}

public class TestDemo {
	public static void main(String args[]) {
		B b = new B();
		b.fun();
	}
}

当发生了覆写之后,此时会调用实例化子类中中已经被覆写的方法。

一个类可能会产生多个子类,每个子类都一定会有自己的实现。

class A {
	public void fun() {
		System.out.println("A类中的fun()");
	}
}

class B extends A {
	public void fun() {// 此处为覆写
		System.out.println("B类中的fun()");
	}
}

class C extends A {
	public void fun() {// 此处为覆写
		System.out.println("C类中的fun()");
	}
}

public class TestDemo {
	public static void main(String args[]) {
		B b = new B();
		C c = new C();
		b.fun();
		c.fun();
	}
}

覆写结果的分析要素:

  • 观察实例化的是哪一个类;
  • 观察这个实例化的类里面调用的方法是否已经被覆写过的,如果没有覆写过,调用父类的。

覆写的使用原则(被动原则):

如果现在发现父类中的方法名称功能不足(不适合于本子类),但是又必须使用这个方法名称的时候,就需要采用覆写这一概念实现。

 

以上的代码确实已经实现了覆写的功能,但是如果想要更好的实现覆写的操作,还必须考虑到权限问题,被子类所覆写的方法不能够拥有比父类更严格的访问控制权限。

对于访问控制权限我们已经学习过三个:public>default>private,也就是说private的访问权限是最严格的,即:如果父类的方法使用的是public声明,那么子类覆写此方法的时候只能使用public,如果父类的方法使用的是default,那么子类覆写方法的时候只能使用default或public。99%情况下只要是方法都使用public声明。

范例:正确的覆写

class A {
	public void fun() {
		System.out.println("A类中的fun()");
	}
}

class B extends A {
	public void fun() {// 此处为覆写
		System.out.println("B类中的fun()");
	}
}
class A {
	void fun() {
		System.out.println("A类中的fun()");
	}
}

class B extends A {
	public void fun() {// 此处为覆写
		System.out.println("B类中的fun()");
	}
}

范例:错误的覆写

class A {
	public void fun() {
		System.out.println("A类中的fun()");
	}
}

class B extends A {
	void fun() {// 此处为覆写
		System.out.println("B类中的fun()");
	}
}

此时子类中使用了default权限,相对于父类中的public属于更加严格的范畴。

 

疑问?如果父类中方法使用了private声明,子类使用了public声明方法,那么叫覆写吗?

从概念上来讲,父类的方法是private,属于小范围权限,而public属于扩大范围权限。权限上符合于覆写要求。

下面先抛开private不看,先使用一个正常的覆写操作。

class A {
	public void fun() {
		print();
	}

	public void print() {
		System.out.println("下午好");
	}
}

class B extends A {
	public void print() {// 覆写print()
		System.out.println("你好");
	}
}

public class TestDemo {
	public static void main(String args[]) {
		B b = new B();
		b.fun();
	}
}

下面使用private声明父类中的方法:

class A {
	public void fun() {
		print();
	}

	private void print() {
		System.out.println("下午好");
	}
}

class B extends A {
	public void print() {// 覆写print()
		System.out.println("你好");
	}
}

public class TestDemo {
	public static void main(String args[]) {
		B b = new B();
		b.fun();
	}
}

这个时候发现子类中根本就没有覆写print()方法,也就是说如果使用了private声明,那么这个方法对子类而言是不可见的,就算子类定义了一个与之完全相同的符合于覆写要求的方法,那么也不能够发生覆写。这个时候子类所写的方法实际上就相当于子类自己定义了一个新的方法。

一旦有了覆写之后会发现,默认情况下子类所能够调用的一定是被覆写过的方法。为了能够明确的由子类调用父类中已经被覆写的方法,那么可以使用“super.方法()”来进行访问。

class A {
	public void print() {
		System.out.println("下午好");
	}
}

class B extends A {
	public void print() {// 覆写print()
		super.print();
		System.out.println("你好");
	}
}

public class TestDemo {
	public static void main(String args[]) {
		B b = new B();
		b.print();
	}
}

关于super.方法()与this.方法的区别:

· 使用“this.方法()”会首先查找本类中是否存在有要调用方法名称,如果存在则直接调用,如果不存在,则查找父类中是否具备此方法,如果有就调用,如果没有,则会发生编译时的错误提示;

· 使用“super.方法()”明确的表示调用的不是子类的方法(不查找子类中是否存在有此方法),而直接调用父类中的指定方法。

 

扩展题目:请解释重载与覆写的区别?(请解释Overloading与Overrid的区别?)

在使用Overloading的时候,返回值能否不同?

No

区别

重载

覆写

1

英文单词

Overloading

Overrid

2

发生范围

发生在一个类里面

发生在继承关系中

3

定义

方法名称相同,参数的类型及个数不同

方法名称相同,参数的类型及个数相同,方法返回值相同

4

权限

没有权限限制

被覆写的方法不能拥有比父类更为严格的访问控制权限

在发生重载关系的时候,返回值可以不同,但是考虑到程序设计的统一性,重载时尽量保证方法的返回值类型相同。


二、属性的覆盖

如果说现在子类定义了和父类完全相同的属性名称的时候,就称为属性的覆盖。

范例:观察属性覆盖

class A {
	String info = "hello";
}

class B extends A {
	int info = 100;// 名称相同

	public void print() {
		System.out.println(super.info);
		System.out.println(this.info);
	}
}

public class TestDemo {
	public static void main(String args[]) {
		B b = new B();
		b.print();
	}
}

我们一直强调,在任何的开发之中,类中的属性必须封装(99%),那么一旦封装之后,这样的覆盖是没有任何意义的,因为父类定义的私有属性子类根本就看不见,更不会互相影响了。

 

比较:关于super与this的区别。

 

No

区别

this

super

1

功能

调用本类构造、本类方法、本类属性

子类调用父类构造、父类方法、父类属性

2

形式

先查找本类中是否存在有指定的调用结构,如果有则直接使用,如果没有则调用父类定义

不查找子类,直接调用父类操作

3

当前对象

表示本类的当前对象

-

在以后的开发之中,对于本类或者是父类中的操作,强烈建议加上“this.”或者是“super.”,这样好区分。

 

 

<think>好的,用户问的是队列的含义和实现方式。首先我需要明确“队列”这个术语的具体定义。在常规的数据结构教材中,可能没有直接提到“”这个词,但结合上下文,可能是指队列的入,比如循环队列在满时盖旧元素的情况。 用户之前的问题是关于队列的实现,所以这次可能想了解特定场景下的队列操作,比如当队列满了之后如何处理新元素。可能意味着当队列已满时,新加入的元素会盖掉最早的元素,这种结构通常称为循环队列或者环形缓冲区。 接下来要考虑实现方式。队列的基本操作是入队和出队,而的情况通常发生在固定大小的队列中。当队列满时,入队操作会导致队头元素被盖,同时调整队头和队尾指针。需要处理队列的空和满的状态判断,通常循环队列会浪费一个存储单元来区分空和满,但的情况下可能不需要,因为允许盖。 然后参考用户提供的引用内容,虽然引用[1]提到的是Java中列表转数组的方法,引用[2]讲的是栈的应用,可能与当前问题关联不大。但需要确保回答符合用户之前的问题历史,可能用户之前在了解数据结构的实现,比如栈和队列的基础代码。 接下来需要组织回答结构,先解释队列的含义,再说明实现步骤,包括初始化、入队、出队等方法。然后给出代码示例,比如用Java或Python实现循环队列,并处理的情况。最后生成相关问题,帮助用户深入理解。 要确保使用正确的中文术语,避免技术术语翻译错误。同时检查代码的正确性,比如循环队列的指针移动和条件判断。可能还需要比较普通队列和队列的区别,强调场景的应用,如实时数据流处理等。 总结步骤:定义队列实现方式(初始化、指针管理、满队处理),代码示例,应用场景,相关问题。</think>### 队列的“实现解析 “队列”通常指**固定大小的循环队列在满容量时自动盖最旧数据**的实现方式。这种设计常见于需要持续处理数据流的场景(如实时传感器数据缓存),其核心特征是新元素会盖过期数据。 --- ### 实现步骤及代码示例(Python) #### 1. 数据结构定义 初始化固定大小的数组,维护头尾指针: ```python class CircularQueue: def __init__(self, capacity): self.capacity = capacity self.queue = [None] * capacity self.head = 0 # 队头索引 self.tail = 0 # 下一个可入位置 self.size = 0 # 当前元素数量 ``` #### 2. 入队逻辑 当队列满时盖头部元素: ```python def enqueue(self, item): if self.size == self.capacity: # 队列已满时盖 self.head = (self.head + 1) % self.capacity self.size -= 1 # 丢弃队头元素 self.queue[self.tail] = item self.tail = (self.tail + 1) % self.capacity self.size += 1 ``` #### 3. 标准出队逻辑 ```python def dequeue(self): if self.size == 0: raise Exception("Queue is empty") item = self.queue[self.head] self.head = (self.head + 1) % self.capacity self.size -= 1 return item ``` #### 4. 状态查询方法 ```python def is_full(self): return self.size == self.capacity def is_empty(self): return self.size == 0 ``` --- ### 关键特性对比 | 特性 | 普通队列 | 队列 | |--------------------|------------------|----------------------| | 满队处理 | 拒绝入队/抛异常 | 盖最早元素 | | 内存占用 | 动态增长 | 固定预分配 | | 应用场景 | 任务调度 | 实时数据流处理 | --- ### 典型应用场景 1. **日志滚动记录**:保留最近N条日志 2. **音视频缓冲区**:持续盖过期帧数据[^2] 3. **实时监控系统**:仅显示最新指标 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值