方法覆盖详解.

思考1:什么时候我们会考虑使用方法覆盖"呢?

子类继承父类之后,当继承过来的方法无法满足当前子类的业务需求时,
子类有权利对这个方法进行重新编写,有必要进行方法的覆盖"。
方法覆盖又叫做:方法重写(重新编写),英语单词叫做: Override、Overwrite, 都可以
比较常见的:方法覆盖、方法重写、override  

思考2:当我们代码怎么编写的时候,在代码级别上构成了方法覆盖呢? 

条件一:两个类必须要有继承关系。

条件二:重写之后的方法和之前的方法具有:
    相同的返回值类型、
    相同的方法名、
    相同的形式参数列表。

条件三:访问权限不能更低,可以更高。(protected关键字)
[public权限比protected高 protected表示受保护的,没有public开放、](这个先记住。)

条件四:重写之后的方法不能比之前的方法抛出更多的异常,可以更少。(先记住)

注意事项:

注意1:方法覆盖只是针对于方法,和属性无关。
注意2:私有方法无法覆盖。
注意3:构造方法不能被继承,所以构造方法也不能被覆盖。
注意4:方法覆盖只是针对于"实例方法","静态方法覆盖"没有意义。 

分析:下列代码需要进行方法重写:

public class OverrideTest01
{
	public static void main(String[] args){
		// 创建一个鸟对象
		Bird b =new Bird();
		b.move(); // 动物在移动
		b.eat(); //都喜欢吃
	}
}


// 父类
class Animal
{	
	// 子类不需要改进的代码[用继承,子类不用再重写]
	public void eat(){
		System.out.println("都喜欢吃~");
	}
	// 移动
	public void move(){
		System.out.println("动物在移动~");
	}
}

class Bird extends Animal
{
	// 子类继承父类中,有些"行为"是不需要改进的比如eat()方法,有一些"行为"可能面临着必须改进
	// 因为父类中继承过来的方法已经无法满足子类的业务需求

	// 鸟儿在移动的时候希望输出的是鸟儿在飞翔~
}

class Cat extends Animal
{
	// 猫在移动的时候,希望输出"猫在走猫步~"
}

方法重写后的代码:

public class OverrideTest01
{
	public static void main(String[] args){
		// 创建一个鸟对象
		Bird b =new Bird();
		b.move(); 
		b.sing(1); //sing(int)方法传参时
		b.sing(); //sing()方法不传参时
		// 创建一个猫对象
		Cat c =new Cat();
		c.move();
		
	}
}


// 父类
class Animal
{	
	// 移动
	public void move(){
		System.out.println("动物在移动~");
	}

	public void sing(int i){
		System.out.println("Animal 在唱歌~");
	}
}

class Bird extends Animal
{	
	// 鸟儿在移动的时候希望输出的是鸟儿在飞翔~
	// 对move方法重写
	// 最好将父类中的move方法原封不动的复制过来 (不建议手动编写)
	public void move(){
		System.out.println("鸟儿在飞翔~");
	}
	
	//分析:这个sing()和父类的sing(int i)方法是否发生了覆盖?
		// 没有发生覆盖 [也就是说子类Bird不仅继承了父类的sing(int i)方法 还重新写了一个sing()方法
	public void sing(){
		System.out.println("bird 在唱歌~");
	}
}

class Cat extends Animal
{
	// 猫在移动的时候,希望输出"猫在走猫步~"
	// 方法重写
	public void move(){
		System.out.println("猫儿在走猫步~");
	}
}

运行结果:

 条件三:访问权限不能更低,可以更高。(protected关键字)

public class OverrideTest01
{
	public static void main(String[] args){
		// 创建一个鸟对象
		Bird b =new Bird();
		b.move(); 	
	}
}


// 父类
class Animal
{	
	// 移动
	public void move(){
		System.out.println("动物在移动~");
	}


}

class Bird extends Animal
{	
	protected void move(){	// 访问权限变低 报错:正在尝试分配更低的访问权限; 以前为public
		System.out.println("鸟儿在飞翔~");
	}
	
}

条件四:重写之后的方法不能比之前的方法抛出更多的异常,可以更少。

public class OverrideTest01
{
	public static void main(String[] args){
		// 创建一个鸟对象
		Bird b =new Bird();
		b.move(); 	
	}
}


// 父类
class Animal
{	
	// 移动
	public void move(){
		System.out.println("动物在移动~");
	}


}

class Bird extends Animal
{	
	public void move() throws Exception {	// 在子类重写后抛出异常 报错:被覆盖的方法未抛出Exception
		System.out.println("鸟儿在飞翔~");
	}
	
}public class OverrideTest01
{
	public static void main(String[] args){
		// 创建一个鸟对象
		Bird b =new Bird();
		b.move(); 	
	}
}


// 父类
class Animal
{	
	// 移动
	public void move(){
		System.out.println("动物在移动~");
	}


}

class Bird extends Animal
{	
	public void move() throws Exception {	// 在子类重写后抛出异常 报错:被覆盖的方法未抛出Exception
		System.out.println("鸟儿在飞翔~");
	}
	
}

 运行结果:

典型覆盖案例

public class OverrideTest01
{	
	public static void main(String[] args){
		// 创建中国人对象
		ChinaPeople c =new ChinaPeople();
		c.setName("jun");
		c.speak();
		//创建美国人对象
		SmallDog s =new SmallDog();
		s.setName("junker");
		s.speak();
		
		
	}
}

// 人
class People
{
	private String name;

	// 构造方法
	public People(){}
	public People(String name){
		this.name =name;
	}
	// 设立关卡
	public String getName(){
		return this.name;
	}
	public void setName(String name){
		this.name =name;
	}
	// 实例方法
	public void speak(){
		System.out.println(this.name+"人都会说话...");
	}
}

// 中国人
// 中国人说中国话 所以子类需要对父类的speak()方法重写
class ChinaPeople extends People
{	
	private String no;
	// 实例方法
	public void speak(){
		System.out.println(this.getName()+":用汉语说话...");
	}
}	

// 美国人
class SmallDog extends People{
	
	public void speak(){
		System.out.println(this.getName()+":汪汪汪~");
	}
}

静态方法不存在方法重写

1、方法覆盖必须和多态机制联合在一起才有意义
    Animal a =new Cat();
    a.move();
    要的是什么效果?
         编译的时候move()的方法是Animal类的方法,然后静态绑定
         运行的时候自动调用到子类重写的move()方法上
    
    假如没有多态机制,只有方法覆盖机制,你觉得有意义吗?
         没有多态机制的话,方法覆盖可有可无
    
    2、静态方法中存在方法重写吗?
    静态方法的执行不需要对象,而方法重写是子类继承父类存在对象的关系,所以说静态方法不存在方法重写
 

// 测试程序
public class OOTest01
{
	public static void main(String[] args){
		/*
		静态方法是"类名."的方式进行访问,不建议使用"引用."

		*/
		Animal a =new Cat();
		a.doSome(); // 结果:Animal的doSome方法执行 而不是Cat的doSome方法 所以静态方法不存在方法重写
		
	}
}

// 父类
class Animal
{
	public static void doSome(){
		System.out.println("Animal的doSome方法执行");
	}
}
// 子类
class Cat extends Animal
{
	public static void doSome(){
		System.out.println("Cat的doSome方法执行");
	}
}

 私有方法不能被重写

/*
私有方法不能被覆盖
*/

public class OOTest02
{
	private void doSome(){
		System.out.println("私有方法的doSome开始执行");
	}
	public static void main(String[] args){
		// 多态
		OOTest02 o =new T();
		o.doSome(); // 输出结果:私有方法的doSome开始执行
		// 能输出私有方法的doSome 私有方法必须在本类中执行,在其他类则不能访问私有方法和私有变量
		// 输出结果说明子类没有发生方法重写机制
	} 
}

class T extends OOTest02
{	
	// 尝试重写父类的doSome方法[重写前:需要先继承]
	public void doSome(){
		System.out.println("子类T的doSome方法开始执行");
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值