final关键字多态

目录

final关键字

多态概述

弊端

多态中的转型问题


final关键字

/*
	继承的代码体现
	
	由于继承中方法有一个现象:方法重写。
	所以,父类的功能,就会被子类给覆盖调。
	有些时候,我们不想让子类去覆盖掉父类的功能,只能让他使用。
	这个时候,针对这种情况,Java就提供了一个关键字:final
	
	final:最终的意思。常见的是它可以修饰类,方法,变量。
*/
class Fu {
	public final void show() {
		System.out.println("这里是绝密资源,任何人都不能修改");
	}
}

class Zi extends Fu {
	// Zi中的show()无法覆盖Fu中的show()
	public void show() {
		System.out.println("这是一堆垃圾");
	}
}

class ZiDemo {
	public static void main(String[] args) {
		Zi z = new Zi();
		z.show();
	}
}
/*
	final可以修饰类,方法,变量
	
	特点:
		final可以修饰类,该类不能被继承。
		final可以修饰方法,该方法不能被重写。(覆盖,复写)
		final可以修饰变量,该变量不能被重新赋值。因为这个变量其实常量。
		
	常量:
		A:字面值常量
			"hello",10,true
		B:自定义常量
			final int x = 10;
*/

//final class Fu //无法从最终Fu进行继承

class Fu {
	public int num = 10;
	public final int num2 = 20;

	/*
	public final void show() {
	
	}
	*/
}

class Zi extends Fu {
	// Zi中的show()无法覆盖Fu中的show()
	public void show() {
		num = 100;
		System.out.println(num);
		
		//无法为最终变量num2分配值
		//num2 = 200;
		System.out.println(num2);
	}
}

class FinalDemo {
	public static void main(String[] args) {
		Zi z = new Zi();
		z.show();
	}
}
/*
	面试题:final修饰局部变量的问题
		基本类型:基本类型的值不能发生改变。
		引用类型:引用类型的地址值不能发生改变,但是,该对象的堆内存的值是可以改变的。
*/
class Student {
	int age = 10;
}

class FinalTest {
	public static void main(String[] args) {
		//局部变量是基本数据类型
		int x = 10;
		x = 100;
		System.out.println(x);
		final int y = 10;
		//无法为最终变量y分配值
		//y = 100;
		System.out.println(y);
		System.out.println("--------------");
		
		//局部变量是引用数据类型
		Student s = new Student();
		System.out.println(s.age);
		s.age = 100;
		System.out.println(s.age);
		System.out.println("--------------");
		
		final Student ss = new Student();
		System.out.println(ss.age);
		ss.age = 100;
		System.out.println(ss.age);
		
		//重新分配内存空间
		//无法为最终变量ss分配值
		ss = new Student();
	}
}
/*
	final修饰变量的初始化时机
		A:被final修饰的变量只能赋值一次。
		B:在构造方法完毕前。(非静态的常量)
*/
class Demo {
	//int num = 10;
	//final int num2 = 20;
	
	int num;
	final int num2;
	
	{
		//num2 = 10;
	}
	
	public Demo() {
		num = 100;
		//无法为最终变量num2分配值
		num2 = 200;
	}
}

class FinalTest2 {
	public static void main(String[] args) {
		Demo d = new Demo();
		System.out.println(d.num);
		System.out.println(d.num2);
	}
}

多态概述

l多态概述

某一个事物,在不同时刻表现出来的不同状态。

举例:

猫可以是猫的类型。猫 m = new ();

同时猫也是动物的一种,也可以把猫称为动物。

动物 d = new (); 从右边往左念

在举一个例子:水在不同时刻的状态

l多态前提和体现

有继承关系 

有方法重写 

有父类引用指向子类对象

/*
	多态:同一个对象(事物),在不同时刻体现出来的不同状态。
	举例:
		猫是猫,猫是动物。
		水(液体,固体,气态)。
		
	多态的前提:
		A:要有继承关系。
		B:要有方法重写。
			其实没有也是可以的,但是如果没有这个就没有意义。
				动物 d = new 猫();
				d.show();
				动物 d = new 狗();
				d.show();
		C:要有父类引用指向子类对象。
			父 f =  new 子();
			
	用代码体现一下多态。
	
	多态中的成员访问特点:
		A:成员变量
			编译看左边,运行看左边。
		B:构造方法
			创建子类对象的时候,访问父类的构造方法,对父类的数据进行初始化。
		C:成员方法
			编译看左边,运行看右边。
		D:静态方法
			编译看左边,运行看左边。
			(静态和类相关,算不上重写,所以,访问还是左边的)
			
		由于成员方法存在方法重写,所以它运行看右边。
*/
class Fu {
	public int num = 100;

	public void show() {
		System.out.println("show Fu");
	}
	
	public static void function() {
		System.out.println("function Fu");
	}
}

class Zi extends Fu {
	public int num = 1000;
	public int num2 = 200;

	public void show() {
		System.out.println("show Zi");
	}
	
	public void method() {
		System.out.println("method zi");
	}
	
	public static void function() {
		System.out.println("function Zi");
	}
}

class DuoTaiDemo {
	public static void main(String[] args) {
		//要有父类引用指向子类对象。
		//父 f =  new 子();
		Fu f = new Zi();
		System.out.println(f.num);
		//找不到符号
		//System.out.println(f.num2);
		
		f.show();
		//找不到符号
		//f.method();
		f.function();
	}
}
/*
	多态的好处:
		A:提高了代码的维护性(继承保证)
		B:提高了代码的扩展性(由多态保证)
		
	猫狗案例代码
*/
class Animal {
	public void eat(){
		System.out.println("eat");
	}
	
	public void sleep(){
		System.out.println("sleep");
	}
}

class Dog extends Animal {
	public void eat(){
		System.out.println("狗吃肉");
	}
	
	public void sleep(){
		System.out.println("狗站着睡觉");
	}
}

class Cat extends Animal {
	public void eat() {
		System.out.println("猫吃鱼");
	}
	
	public void sleep() {
		System.out.println("猫趴着睡觉");
	}
}

class Pig extends Animal {
	public void eat() {
		System.out.println("猪吃白菜");
	}
	
	public void sleep() {
		System.out.println("猪侧着睡");
	}
}

//针对动物操作的工具类
class AnimalTool {
	private AnimalTool(){}

	/*
	//调用猫的功能
	public static void useCat(Cat c) {
		c.eat();
		c.sleep();
	}
	
	//调用狗的功能
	public static void useDog(Dog d) {
		d.eat();
		d.sleep();
	}
	
	//调用猪的功能
	public static void usePig(Pig p) {
		p.eat();
		p.sleep();
	}
	*/
	public static void useAnimal(Animal a) {
		a.eat();
		a.sleep();
	}
	
}

class DuoTaiDemo2 {
	public static void main(String[] args) {
		//我喜欢猫,就养了一只
		Cat c = new Cat();
		c.eat();
		c.sleep();
		
		//我很喜欢猫,所以,又养了一只
		Cat c2 = new Cat();
		c2.eat();
		c2.sleep();
		
		//我特别喜欢猫,又养了一只
		Cat c3 = new Cat();
		c3.eat();
		c3.sleep();
		//...
		System.out.println("--------------");
		//问题来了,我养了很多只猫,每次创建对象是可以接受的
		//但是呢?调用方法,你不觉得很相似吗?仅仅是对象名不一样。
		//我们准备用方法改进
		//调用方式改进版本
		//useCat(c);
		//useCat(c2);
		//useCat(c3);
		
		//AnimalTool.useCat(c);
		//AnimalTool.useCat(c2);
		//AnimalTool.useCat(c3);
		
		AnimalTool.useAnimal(c);
		AnimalTool.useAnimal(c2);
		AnimalTool.useAnimal(c3);
		System.out.println("--------------");
		
		//我喜欢狗
		Dog d = new Dog();
		Dog d2 = new Dog();
		Dog d3 = new Dog();
		//AnimalTool.useDog(d);
		//AnimalTool.useDog(d2);
		//AnimalTool.useDog(d3);
		AnimalTool.useAnimal(d);
		AnimalTool.useAnimal(d2);
		AnimalTool.useAnimal(d3);
		System.out.println("--------------");
		
		//我喜欢宠物猪
		//定义一个猪类,它要继承自动物,提供两个方法,并且还得在工具类中添加该类方法调用
		Pig p = new Pig();
		Pig p2 = new Pig();
		Pig p3 = new Pig();
		//AnimalTool.usePig(p);
		//AnimalTool.usePig(p2);
		//AnimalTool.usePig(p3);
		AnimalTool.useAnimal(p);
		AnimalTool.useAnimal(p2);
		AnimalTool.useAnimal(p3);
		System.out.println("--------------");
		
		//我喜欢宠物狼,老虎,豹子...
		//定义对应的类,继承自动物,提供对应的方法重写,并在工具类添加方法调用
		//前面几个必须写,我是没有意见的
		//但是,工具类每次都改,麻烦不
		//我就想,你能不能不改了
		//太简单:把所有的动物都写上。问题是名字是什么呢?到底哪些需要被加入呢?
		//改用另一种解决方案。
		
	}
	
	/*
	//调用猫的功能
	public static void useCat(Cat c) {
		c.eat();
		c.sleep();
	}
	
	//调用狗的功能
	public static void useDog(Dog d) {
		d.eat();
		d.sleep();
	}
	*/
}

弊端

*
	多态的弊端:
		不能使用子类的特有功能。
*/
class Fu {
	public void show() {
		System.out.println("show fu");
	}
}

class Zi extends Fu {
	public void show() {
		System.out.println("show zi");
	}
	
	public void method() {
		System.out.println("method zi");
	}

}

class DuoTaiDemo3 {
	public static void main(String[] args) {
		//测试
		Fu f = new Zi();
		f.show();
		f.method();
	}
}

多态中的转型问题

猜你喜欢

转载自blog.csdn.net/moonlightpeng/article/details/91385730
今日推荐