Java零基础(十)之多态+抽象类

  1. 多态(重点)

生活中的多态:客观事物在人脑中的主观反应;也就是说对象与某个类间存在“is a”关系
例如:大黄是一条狗,也是一个动物,这种关系就是多态的形成

程序中的多态:父类引用指向子类对象,在程序中形成了多态
用法: 可以调用父类的方法,但是不能调用子类独有的方法

多态核心

//案例:大黄是一条狗,也是一个动物
//分析: 类: 狗类     动物类    对象: 大黄       方法:  动物类-吃    狗类-跑

class Animal{
    
    
	public void eat() {
    
    
		System.out.println("动物正在吃...");
	}
}

class Dog extends Animal{
    
    
	public void run() {
    
    
		System.out.println("大黄正在跑...");
	}
}
public class Test1 {
    
    
	public static void main(String[] args) {
    
    
		/*
		Dog dog = new Dog();  //把狗当成狗类看待-->可以调子类自身方法,也可以根据继承调父类方法
		dog.run();
		dog.eat();
		*/
		
		Animal animal = new Dog(); //多态的核心-->把狗当成动物来看待,可以调动物类的方法,但狗类独有方法不能调用
		animal.eat();  
		//animal.run();   //不能调子类独有方法
	}
}

多态直接引用

在这里插入图片描述

//案例:大黄是一条狗,也是一个动物
//分析: 类: 狗类     动物类    对象: 大黄       方法:  动物类-吃    狗类-跑

//升级:狗类重写父类的方法,应该如何调用?

//多态的应用: 父类引用指向子类对象,优先调用子类重写的方法
//方式1:子类对象直接赋值给父类

class Animal2{
    
    
	public void eat() {
    
    
		System.out.println("动物正在吃...");
	}
}

class Dog2 extends Animal2{
    
    
	public void run() {
    
    
		System.out.println("大黄正在跑...");
	}
	
	@Override
	public void eat() {
    
    
		System.out.println("大黄正在吃...");
	}
}
public class Test2 {
    
    
	public static void main(String[] args) {
    
    
		Animal2 animal2 = new Dog2();
		animal2.eat();  //父类引用指向子类对象,优先调用子类重写的方法
	}
}

多态以传参方式出现

案例: 老师开着法拉利牌自行车去上班
分析:
类: 老师类 自行车类
对象: new new
属性: 姓名 品牌
方法: 开 运转

升级: 老师法拉利牌开汽车…

问题:当我们扩展了开地铁类,飞机类,大炮,那么在Teacher类中需要增加很多开的方法(冗余太多,麻烦,可维护性不强)
改造: 自行车,汽车,地铁,飞机等都是交通工具,都具备运转功能

多态的好处: 使得程序的扩展性,可维护性更强

class JiaoTongTool{
    
    
	public void run() {
    
    
		System.out.println("交通工具在运转...");
	}
}

class Bike extends JiaoTongTool{
    
    
	@Override
	public void run() {
    
    
		System.out.println("自行车运转: 轮子转啊转,以每小时50公里速度~");
	}
}

class Car extends JiaoTongTool{
    
    
	@Override
	public void run() {
    
    
		System.out.println("汽车运转:以每小时100公里速度前进~");
	}
	
}

class Teacher{
    
    
	//重写  VS 重载
	//重载: 在同一个类中,方法名相同,参数个数或类型不同
	//重写:在继承关系中,子类返回值,方法名,参数类型和父类完全一致,且子类权限大于等于父类
	      
	//-----------重载方法----------
	/*
	public void start(Bike bike) {//Bike bike = new Bike();
		bike.run();  //自行车的运转
	}
	
	public void start(Car car) {
		car.run();  //自行车的运转
	}*/

	//面向对象的设计原则:ocp原则,开闭原则
	//o-open: 对外新增的代码持开放状态-扩展性  (升级新增飞机类,大炮等)
	//c:close:对内修改的代码持关闭状态-灵活性,可维护性 (Teacher类的start方法不要变更,只需用交通工具类接收)
	
	//以传参形式实现多态:
	//应用:父类引用指向子类对象,可调用子类重写方法
	public void start(JiaoTongTool tool) {
    
    
		tool.run();  //不要看谁调的,要看谁传的
	}

}

public class Test {
    
    
	public static void main(String[] args) {
    
    
		Teacher teacher = new Teacher();
		teacher.start(new Bike());  //1.老师开自行车
		teacher.start(new Car());     //2.老师开汽车
		
		//new Bike().run();  //等价Teacher的start方法里面bike对象的调用
	}
}

在这里插入图片描述
在这里插入图片描述

传参方式实现多态案例2

//案例:主人喂养动物,狗是动物,猫是动物,以传参形式实现多态
//抽取: 父类引用指向子类对象,调子类重写方法--->狗,猫是动物,具备吃的行为
//类: 主人类    动物类    狗类    猫类      
//行为: 主人类: 喂养       动物类:吃      狗,猫: 重写吃

//案例1:金鱼,乌龟都是水生动物,具备吃的行为
//案例2:面条,面包都是食物,都具备提高营养能力
//案例3:王者,吃鸡都是游戏,都具备充值能力

class Animal{
    
    
	public void eat() {
    
    
		System.out.println("动物在吃...");
	}
}


class Dog extends Animal{
    
    
	@Override
	public void eat() {
    
    
		System.out.println("狗在吃...");
	}
}

class Cat extends Animal{
    
    
	@Override
	public void eat() {
    
    
		System.out.println("猫在吃...");
	}
}

class Master{
    
    
	public void feed(Animal animal) {
    
    //多态
		animal.eat();  //谁传给我,就是谁在吃
	}
}
public class Test2 {
    
    
	public static void main(String[] args) {
    
    
		Master master = new Master();
		master.feed(new Dog()); //主人喂狗,狗在吃
		master.feed(new Cat()); //主人喂猫,猫在吃 
	}
}

多态以返回值形式出现

//案例:主人购买动物,选择购买编号:1.买狗    2.买鸟

//分析: 
//类:  主人类             动物类   狗类   鸟类      
//行为:购买                      叫

class Animal{
    
    
	public void bark() {
    
    
		System.out.println("动物在叫..");
	}
}

class Dog extends Animal{
    
    
	@Override
	public void bark() {
    
    
		System.out.println("狗在叫..");
	}
}

class Bird extends Animal{
    
    
	@Override
	public void bark() {
    
    
		System.out.println("鸟在叫...");
	}
}

class Master{
    
    
	public Animal buy(int num) {
    
    
		switch (num) {
    
    
			case 1:
				return new Dog();  //多态以返回值方式出现
			case 2:
				return new Bird();
			default:
				return null;
		}
	}
}
public class Test {
    
    
	public static void main(String[] args) {
    
    
		System.out.println("请输入你要购买的宠物: 1.狗   2.鸟");
		Scanner sc = new Scanner(System.in);
		int num = sc.nextInt();
		Master master = new Master();
		//多态以返回值方式出现
		Animal animal = master.buy(num);  //Animal a = new Dog(); 
		if(animal!=null) {
    
    
			animal.bark();  //调重写方法
		}else {
    
    
			System.out.println("没有这个购买的宠物");
		}
		
	}
}

在这里插入图片描述

导入源码包:

在这里插入图片描述

  1. 抽象类(重点)
    生活中的抽象:从网上搜索动物类,可以具体化子类对象;但是不能具体化动物的对象

程序中的抽象类:有一个类不能够具体化出来对象,这个类就是抽象类
程序中的抽象方法:往往在抽象类中,有这个方法但不能具体实现,这个方法叫做抽象方法

例如: 动物类不能具体化,这个动物类就是抽象类;
动物类一般都有叫的方法,但不能具体实现,叫的方法我们可以设置为抽象方法;
抽象方法用处:作为一个模板,该抽象类的子类必须完成抽象方法的重写

案例: 动物类都有叫的方法,狗类,猫类(子类)完成具体实现
抽取多态: 狗,猫是动物,具备叫的行为

抽象类概述

//抽象类: 限制该类不能被具体化
//抽象类的好处:1.作为模板使用, 2.更自然的使用多态

//抽象类的特点整理:
//1.抽象类能否实例化对象?    不能
//2.能否有构造方法?                可以有
//3.抽象类中能否有非抽象方法?   可以有
//4.抽象类中能否没有抽象方法?   可以,但一般都要写抽象方法
//5.父类是抽象类,子类必须重写父类方法吗?    不是必须的,可以把自身变为抽象类
//6.有抽象方法的类必须是抽象类吗?  是的

abstract class Animal{
    
    
	public Animal() {
    
    }  //可以有构造方法,交给子类调用
	
	public void eat(){
    
    }  //有非抽象方法
	
	//抽象类中的一些方法,往往有这个方法,但没法实现,这样的方法设置为抽象方法
	//抽象方法作为模板
	public abstract void bark();
	
}

 //The type Dog must implement the inherited abstract method Animal.bark()
//父类为抽象类,子类有两种处理方案
//1.子类要重写父类的方法
//2.将子类也变为抽象类,交给Dog子类去完成
class Dog extends Animal{
    
    

	@Override
	public void bark() {
    
    
		System.out.println("狗正在旺旺旺地叫...");
	}
	
	public void run() {
    
    
		System.out.println("狗正在跑...");
	}
}

abstract class Cat extends Animal{
    
    
}
public class Test1 {
    
    
	public static void main(String[] args) {
    
    
		//Animal animal = new Animal();  //不合适
		
		//抽象类实现多态: 抽象类指向子类对象,即可调用子类重写方法
		//Dog dog = new Dog();  //? 
		Animal animal = new Dog();  //多态,扩展性,维护性更强
		animal.bark();
		//animal.run();  //不能调子类独有方法(当次动物看待,只能调动物的方法或子类重写的)
	}
}

抽象类案例

/*
 案例: 老师开着法拉利牌自行车去上班

改造: 自行车,汽车,地铁,飞机等都是交通工具,都具备运转功能
将交通工具类变为抽象类,通过抽象类实现多态
分析: 交通工具类不能具体化---抽象类
       交通工具的运行功能---有这个功能,但不知道如何实现,抽象方法
 * */

abstract class JiaoTongTool{
    
    
	public abstract void run();
}

class Bike extends JiaoTongTool{
    
    
	@Override
	public void run() {
    
    
		System.out.println("自行车运转: 轮子转啊转,以每小时50公里速度~");
	}
}

class Car extends JiaoTongTool{
    
    
	@Override
	public void run() {
    
    
		System.out.println("汽车运转:以每小时100公里速度前进~");
	}
	
}

class Teacher{
    
    
	//以传参形式通过抽象类实现多态:
	public void start(JiaoTongTool tool) {
    
    
		tool.run();  //不要看谁调的,要看谁传的
	}

}
public class Test2 {
    
    
	public static void main(String[] args) {
    
    
		//抽象类实现多态
		Teacher teacher = new Teacher();
		teacher.start(new Bike());  //1.老师开自行车
		teacher.start(new Car());     //2.老师开汽车

	}
}

猜你喜欢

转载自blog.csdn.net/weixin_45682261/article/details/125132341
今日推荐