多肽、instanceof

一、子类对象创建过程

1.1 概述

  • 我们已知子类创建出来的对象可以获取到父类中的属性和方法,怎么就能获取到呢?
  • 通过代码我们验证了:创建子类对象的时候,会先创建父类的对象
package com.qf.create;

public class Demo01 {
	public static void main(String[] args) {
		// 创建子类对象的时候,会默认调用父类的构造方法---会先创建父类的对象
		Dog dog = new Dog();
		
	}
}

/**
 * 动物类,所有动物的父类
 * @author Dushine2008
 *
 */
class Animal{
	// 属性
	String type;
	String name;
	int age;
	
	public Animal() {
		super();
		System.out.println("Animal中的空参构造方法被调用啦啦啦啦...");
	}

	public Animal(String type, String name, int age) {
		super();
		this.type = type;
		this.name = name;
		this.age = age;
		System.out.println("Animal中的有参构造方法被调用啦啦啦啦...");
	}

	// 方法
	public void eat() {
		System.out.println("动物需要进食...");
	}
	
	public void sleep() {
		System.out.println("很多动物晚上需要休息...");
	}
}

/**
 * 狗子类,继承Animal
 * @author Dushine2008
 *
 */
class Dog extends Animal{
	// 属性
	String color;
	String gender;
	
	public Dog() {
		super();
	}

	public Dog(String color, String gender) {
		super();
		this.color = color;
		this.gender = gender;
	}

	public Dog(String type, String name, int age,String color, String gender) {
		super(type, name, age);
		this.color = color;
		this.gender = gender;
	}

	// 方法
	public void lookHome() {
		System.out.println("狗子可以看家护院...");
	}
}

1.2 多级继承关系中对象创建过程

  • 如果产生了很多层级的继承关系,创建最底层类的实例的时候会创建所有上一层父类的对象吗?
  • 需要,最底层的子类需要他们的实例属性、方法,而且实例属性是带有默认值的,说明父类们进行了初始化的操作
  • 代码也验证了这种说法
package com.qf.create;

public class Demo01 {
	public static void main(String[] args) {
		// 创建子类对象的时候,会默认调用父类的构造方法---会先创建父类的对象
		Dog dog = new Dog();
		System.out.println(dog);
		
		System.out.println("=========================");
		
		Husky husky = new Husky();
		
	}
}

/**
 * 动物类,所有动物的父类
 * @author Dushine2008
 *
 */
class Animal{
	// 属性
	String type;
	String name;
	int age;
	
	public Animal() {
		super();
		System.out.println("Animal中的空参构造方法被调用啦啦啦啦...");
	}

	public Animal(String type, String name, int age) {
		super();
		this.type = type;
		this.name = name;
		this.age = age;
		System.out.println("Animal中的有参构造方法被调用啦啦啦啦...");
	}

	// 方法
	public void eat() {
		System.out.println("动物需要进食...");
	}
	
	public void sleep() {
		System.out.println("很多动物晚上需要休息...");
	}
}

/**
 * 狗子类,继承Animal
 * @author Dushine2008
 *
 */
class Dog extends Animal{
	// 属性
	String color;
	String gender;
	
	public Dog() {
		super();
		System.out.println("Dog的空参构造方法执行...");
	}

	public Dog(String color, String gender) {
		super();
		this.color = color;
		this.gender = gender;
	}

	public Dog(String type, String name, int age,String color, String gender) {
		super(type, name, age);
		this.color = color;
		this.gender = gender;
	}

	// 方法
	public void lookHome() {
		System.out.println("狗子可以看家护院...");
	}
}

/**
 * Husky类,直接继承Dog,间接继承Animal
 * @author Dushine2008
 *
 */
class Husky extends Dog{
	String feature;

	public Husky() {
		super();
		System.out.println("Husky的空参构造方法...");
	}

	public Husky(String feature) {
		super();
		this.feature = feature;
	}
	
}

二、多态

2.1 定义

  • 生活中的多态

    • 一个事物的多种表现形态
      • 一个人可以使学生、孩子、家长、职员、、、、
  • 程序中的多态

Animal a = new Dog()

父类引用===>子类对象

  • 父类引用指向子类对象时称为多态(要有父类引用指向子类对象)

  • 要有继承关系(要有继承)

  • 只能调用父类自己独有的方法,运行的是子类重写之后的效果(子类要重写父类的方法)

2.2 多态的使用01

  • 声明父类类型的引用,创建子类类型的对象
package com.qf.poly;

import java.util.Arrays;

public class Demo01 {
	public static void main(String[] args) {
		// 声明Human类型的引用,引用指向Human的对象
		Human human = new Human();
		human.dance();
		
		System.out.println("===============================");
		
		// 声明Human类型的引用,引用指向Male
		Human human2 = new Male();
		human2.dance();
		
		System.out.println("===============================");
		
		Human human3 = new Female();
		human3.dance();
		
		System.out.println("===============================");
		
		
	}
}

class Human{
	public void dance() {
		System.out.println("人开心的时候会手舞足蹈...");
	}
}

/**
 * 男人类
 * 继承Human,重写dance方法
 * @author Dushine2008
 *
 */
class Male extends Human{
	@Override
	public void dance() {
		super.dance();
		System.out.println("男人开心的时候跳兔子舞...");
	}
}

/**
 * 女人类
 * 继承Human,重写dance方法
 * @author Dushine2008
 *
 */
class Female extends Human{
	@Override
	public void dance() {
		super.dance();
		System.out.println("女人开心的时候跳广场舞...");
	}
}

2.3 多态的使用02–当做形参

  • 编写一个方法,形参声明为引用类型
  • 调用方法的时候传入此类型或者其子类型对象
package com.qf.poly;

public class Demo02 {
	public static void main(String[] args) {
		// 编写方法,形参声明为一个引用类型,传入此类型或者其子类对象
		Human human1 = new Human();
		dance(human1);
		
		System.out.println("=======================");
		
		Human human2 = new Male();
		dance(human2);
		
		System.out.println("=======================");
		
		Human human3 = new Female();
		dance(human3);
		
		System.out.println("=======================");
		dance(new Human());
		dance(new Male());
		dance(new Female());
	}
	
	/**
	 * 调用human跳舞的方法
	 * 	形参数Human类型
	 * 	human对象有dance方法,调用之
	 * @param human
	 */
	public static void dance(Human human) {
		human.dance();
	}
}

2.4 多态使用方法和属性的情况

  • 调用方法
    • 编译的时候看父类中有没有这个方法
    • 运行的时候看子类是否重写过这个方法
    • 编译时看父类,运行时看子类
    • 编译看左边,运行看右边
  • 调用属性
    • 编译的时候看父类中是否有这个属性
    • 运行的时候依旧是使用父类的属性值
    • 编译时看父类,运行时看父类
    • 编译看左边,运行看左边
package com.qf.poly;

public class Demo03 {
	public static void main(String[] args) {
		Employee employee1 = new Employee();
		employee1.work();
		employee1.bitCard();
		employee1.name = "张三";
		System.out.println(employee1.name);
		
		System.out.println("==========================");
		
		// 多态指向Programmer
		Employee employee2 = new Programmer();
		employee2.work();
		employee2.bitCard();
		// employee2.name = "李思思";
		System.out.println(employee2.name);
		// 多态调用方法的时候,编译的时候看父类中有没有,运行的时候看子类是否重写过
		// employee2.playGame();
		// 多态调用变量的时候,编译的时候看父类中有没有,运行的依旧是父类的属性值
		// employee2.hobby = "穿格子衫";
		System.out.println(employee2.name);
		
	}
}

class Employee{
	// 属性
	String name = "张三";
	String department;
	
	// 方法
	public void work() {
		System.out.println("员工有具体的工作内容...");
	}
	
	public void bitCard() {
		System.out.println("员工上下班需要考勤...");
	}
}

/**
 * 程序员类
 * 	继承了员工类
 * 	重写了work和bitCard方法
 * 	自己有独特的方法
 * @author Dushine2008
 *
 */
class Programmer extends Employee{
	// 属性
	String hobby;
	String name = "IT男";
	
	@Override
	public void work() {
		System.out.println("我们每天吃饭、编码、打产品...");
	}
	
	@Override
	public void bitCard() {
		System.out.println("我们使用指纹打开的方式考勤...");
	}
	
	public void playGame() {
		System.out.println("我们喜欢玩游戏,还能找到游戏的BUG...");
	}
}

/**
 * HR类
 * 	继承员工类,重写work和bitCard方法
 * @author Dushine2008
 *
 */
class HR extends Employee{
	// 属性
	int faceValue;
	
	// 方法
	@Override
	public void work() {
		System.out.println("HR的工作内容和人息息相关...");
	}
	
	@Override
	public void bitCard() {
		System.out.println("HR出外勤的时候可以在线考勤...");
	}
	
	public void recruit() {
		System.out.println("HR负责公司人员的招聘和新员工培训...");
	}
	
}

2.5 多态使用03-当做返回值类型

package com.qf.poly;

import java.util.Scanner;

public class Demo04 {
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		System.out.println("你喜欢哪种动物:1==Dog* 	2==Cat* 	3==Pig* 	其他==Animal:");
		int num = in.nextInt();
		
		Animal animal = getAnimal(num);
		
		animal.eat();
		animal.sleep();
		
	}
	
	/**
	 * 传入编号,获取编号对应的动物
	 * 	1==Dog
	 * 	2==Cat
	 * 	3==Pig
	 * 	其他==Animal
	 * @param num
	 * @return
	 */
	public static Animal getAnimal(int num) {
		
		Animal animal;
		switch (num) {
		case 1:
			animal = new Dog();
			break;
			
		case 2:
			animal = new Cat();
			break;
			
		case 3:
			animal = new Pig();
			break;
		default:
			animal = new Animal();
			
			break;
		}
		
		return animal;
	}
	
}

class Animal{
	// 属性
	String name;
	int age;
	
	public void eat() {
		System.out.println("动物需要吃东西...");
	}
	
	public void sleep() {
		System.out.println("动物需要睡觉来休息...");
	}
}

/**
 * 狗子类
 * 	继承Animal,重写eat和到了sleep方法
 * @author Dushine2008
 *
 */
class Dog extends Animal{
	@Override
	public void eat() {
		System.out.println("狗子喜欢吃的东西和人基本一样...");
	}
	
	@Override
	public void sleep() {
		System.out.println("羡慕狗子的睡觉时间...");
	}
}

/**
 * 猫咪类
 * 	继承Animal,重写了eat和sleep方法
 * @author Dushine2008
 *
 */
class Cat extends Animal{
	@Override
	public void eat() {
		System.out.println("猫咪喜欢吃小鱼...");
	}
	
	public void sleep() {
		System.out.println("猫咪喜欢白天睡觉...");
	}
}

class Pig extends Animal{
	@Override
	public void eat() {
		System.out.println("哼哼喜欢吃西瓜...");
	}
	
	public void sleep() {
		System.out.println("天蓬吃饱了就睡...");
	}
}

三、向上转型和向下转型

3.1 向上转型(装箱)

  • 声明的引用是父类类型,返回比较大,引用指向了子类对象
  • 子类对象自动提升为父类类型,不会报错
  • 但是只能使用声明的父类类型中的属性和方法
  • 多态的基本使用情况
package com.qf.poly;

public class Demo05 {
	public static void main(String[] args) {
		People people1 = new Man();
		people1.dance();
		
	}
}

class People{
	public void dance() {
		System.out.println("人开心的时候跳舞...");
	}
}

/**
 * Man继承People
 * 	重写dance方法
 * 	增加sing方法
 * @author Dushine2008
 *
 */
class Man extends People{
	@Override
	public void dance() {
		System.out.println("男人开心的时候跳舞...");
	}
	
	public void sing() {
		System.out.println("男人开心的时候唱伤心太平洋...");
	}
}

class Woman extends People{
	@Override
	public void dance() {
		System.out.println("女人开心的时候跳广场舞...");
	}
}

3.2 向下转型(拆箱)

  • 声明的类型是子类类型的引用
  • 引用指向的父类类型的对象
  • 如果父类类型引用指向的子类类型的本身,代码不会出现问题,因为转了回来
  • 如果父类引用的不是子类的类型,会报错:ClassCastException
package com.qf.poly;

public class Demo05 {
	public static void main(String[] args) {
		
		People people1 = new Man();
		// 向下转型,需要手动强转,正确的情况
		Man man = (Man)people1;
		man.sing();

		// 手动强转,错误的情况
		People people2 = new Woman();
		Man man2 = (Man) people2;
		man2.sing();
	}
}

class People{
	public void dance() {
		System.out.println("人开心的时候跳舞...");
	}
}

/**
 * Man继承People
 * 	重写dance方法
 * 	增加sing方法
 * @author Dushine2008
 *
 */
class Man extends People{
	@Override
	public void dance() {
		System.out.println("男人开心的时候跳舞...");
	}
	
	public void sing() {
		System.out.println("男人开心的时候唱伤心太平洋...");
	}
}

class Woman extends People{
	@Override
	public void dance() {
		System.out.println("女人开心的时候跳广场舞...");
	}
}

四、instanceof

4.1 定义

  • 判断一个对象是否是指定类型的实例

4.2 案例

package com.qf.poly;

import java.util.Scanner;

public class Demo06 {
	public static void main(String[] args) {
		/**
		 * 传入一个对象,调用这个对象所有的方法
		 */
		System.out.println("" instanceof String);
		
		/**
		 * 提示用书输入一个数字,调用getPerson方法,获取这个数字对应的对象
		 * 调用show方法,传入这个对象,展示这个对象的方法
		 */
		
		Scanner in = new Scanner(System.in);
		System.out.println("请输入你希望看到的职业(1==SoftwareEngineer,,,2==DBA,,,3==ImplementationEngineer,,,其他数字==Person):");
		int num = in.nextInt();
		// 调用getPerson方法获取对象
		Person person = getPerson(num);
		
		// 调用show方法传入Person。展示这个职业的方法
		show(person);
		
	}
	
	/**
	 * 传入数字,获取对应的Person或者其子类的对象
	 * @param num-
	 * @return
	 */
	public static Person getPerson(int num) {
		Person person;
		switch (num) {
		case 1:
			person = new SoftwareEngineer();
			break;
			
		case 2:
			person = new DBA();
			break;
			
		case 3:
			person = new ImplementationEngineer();
			break;

		default:
			person = new Person();
			break;
		}
		
		return person;
	}
	
	
	/**
	 * 展示Person或者其子类的所有方法
	 * @param person
	 */
	public static void show(Person person) {
		if (person == null) {
			System.out.println("Person为null,请重新执行代码传入正确的参数...");
			return;
		}
		
		// person非null
		if (person instanceof SoftwareEngineer) {
			SoftwareEngineer engineer = (SoftwareEngineer) person;
			engineer.eat();
			engineer.sleep();
			engineer.work();
		} else if (person instanceof DBA) {
			DBA dba = (DBA) person;
			dba.eat();
			dba.sleep();
			dba.eatBraisedChicken();
		} else if (person instanceof ImplementationEngineer) {
			ImplementationEngineer engineer = (ImplementationEngineer) person;
			engineer.eat();
			engineer.sleep();
			engineer.work();
		} else if (person instanceof Person) {
			person.eat();
			person.sleep();
		} else {
			System.out.println("您选择的职业暂无相关信息...");
		}
	}
}

/** 父类
 * 	会有一些子类,子类是具体职业的人
 * 	
 */
class Person{
	public void eat() {
		System.out.println("人类需要吃饭...");
	}
	
	public void sleep() {
		System.out.println("人需要睡眠保持精力...");
	}
}

/**
 * 技术总监/经理 
 * 技术支持/维护 技术专员
 * 助理 软件工程师 
 * 程序员
 * 硬件工程师
 * 质量工程师
 * 测试工程师
 * 系统架构师
 * 数据库管理/DBA
 * 游戏设计
 * 开发
 * 网页设计/制作 
 * 语音/视频/图形 
 * 项目经理/主管 
 * 产品经理/专员 
 * 网站运营 
 * 网站编辑
 * 网站策划
 * 网络管理员 网络与信息安全工程师 实施工程师 通信技术工程师
 * */

/**
 * 软件工程师类
 * 	继承Person
 * 	重写eat和sleep方法
 * 	自定义work方法
 * @author Dushine2008
 *
 */
class SoftwareEngineer extends Person{
	
	@Override
	public void eat() {
		System.out.println("我们工作很忙,外卖解决吃饭的问题...");
	}
	
	public void sleep() {
		System.out.println("我们每天坚持午睡,下午精力充沛...");
	}
	
	public void work() {
		System.out.println("我们的工作白天不怎么忙,晚上经常加班...");
	}
}

/**
 * DBA类
 * 	继承Person
 * 	重写eat和work
 * 	自定义eatBraisedChicken方法
 * @author Dushine2008
 *
 */
class DBA extends Person {
	
	@Override
	public void eat() {
		System.out.println("DBA数据库方面的造诣比较深厚,他们吃饭也是点外卖,靠入侵外卖平台的数据库,篡改订单信息吃饭.");
	}
	
	public void sleep() {
		System.out.println("中午不睡下午崩溃,坚持在你午睡攻陷你家的数据库.");
	}
	
	public void eatBraisedChicken() {
		System.out.println("靠技术吃黄焖鸡,吃了整整一年...");
	}
	
}

/**
 * 实施工程师
 * 	继承Person
 * 	重写eat和sleep方法
 * 	自定义work方法
 * @author Dushine2008
 *
 */
class ImplementationEngineer extends Person{
	@Override
	public void eat() {
		System.out.println("经常出差,可以领略各地的美食...");
	}
	
	@Override
	public void sleep() {
		System.out.println("一年到头就处于开房和退房的路上...");
	}
	
	public void work() {
		System.out.println("这是个根客户打交道比较多的工作...");
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值