栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java面向对象 第六天

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java面向对象 第六天

多态性

1,多态性可以理解为事物的多种形态

2,何为多态性:对象的多态性:父类的引用指向子类的对象(或子类的对象赋给父类的引用)

3,多态的使用:虚拟方法调用:
引入对象的多态性之后,我们在编译期只能调用父类中声明的方法,但在运行(执行)期实际运行的是子类重写父类的方法“即编译看左边,运行看右边”。

4,多态性的使用前提:
①有类的继承关系 ;②要有方法的重写。

5,对象的多态性只适用于方法,不适用于属性(属性编译运行都看左边)。

代码理解:

package com.atguigu.java3;
//多态性的使用举例
public class AnimalTest {
	public static void main(String[] args) {
		AnimalTest test=new AnimalTest();
		test.func(new Dog());      //把此匿名对象赋给animal
		test.func(new Cat());      //把此匿名对象赋给animal
	}
	
	public void func(Animal animal){   //相当于:Animal animal=new Dog();-----对象的多态性
		animal.eat();  //此方法体内部只能调用Animal的方法,但运行的是重写的方法
		animal.shout();
	}
	//如果没多态性,需要造很多重载的方法,即需要如下代码

}

class Animal{  //父类
	public void eat(){
		System.out.println("动物饮食");
	}
	public void shout(){
		System.out.println("动物叫");
	}
}

class Dog extends Animal{
	public void eat(){
		System.out.println("狗吃骨头");
	}
	public void shout(){
		System.out.println("汪汪汪");
	}
}
class Cat extends Animal{
	public void eat(){
		System.out.println("猫吃鱼");
	}
	public void shout(){
		System.out.println("喵喵喵");
	}
}

instanceof操作符

关于转型:问题引入:
以Person、Man、Woman为例:

①Person

package com.atguigu.java3;

public class Person {
	String name;
	int age;
	
	public void eat(){
		System.out.println("人:吃饭");
	}
	public void walk(){
		System.out.println("人:走路");
	}

}

②Man

package com.atguigu.java3;

public class Man extends Person {
	boolean isSmoking;
	public void earnMoney(){
		System.out.println("男人负责挣钱养家");
	}
	//对父类中方法进行重写
	public void eat(){
		System.out.println("男人多吃肉,长肌肉");
	}
	public void walk(){
		System.out.println("男人要霸气的走路走路");
	}
}

③Woman

package com.atguigu.java3;

public class Woman extends Person {
	boolean isBeauty;
	public void goShopping(){
		System.out.println("女人喜欢购物");
	}
	public void eat(){
		System.out.println("女人少吃,为了减肥");
	}
	public void walk(){
		System.out.println("女人要窈窕地走路");
	}
}

使用PersonTest测试:

package com.atguigu.java3;
public class PersonTest {
	public static void main(String[] args) {
		Person p1=new Person();
		//引入多态性:父类的引用指向子类的对象
		Person p2=new Man(); 
		//多态性的使用:当调用子父类同名同参数的方法时,实际执行的是子类中重写父类的方法----------称为虚拟方法调用
		p2.eat();   //执行子类中重写父类的方法
		p2.walk();  //执行子类中重写父类的方法
		//不能调用子类所特有的属性和方法:编译时,p2是Person类型,Person中没有定义earnMoney()方法和isSmoking属性
//		p2.earnMoney();  报红
//		p2.isSmoking=true;  报红

		//向下转型:使用强制类型转换符才能调用子类特有的属性和方法
		Man m1=(Man)p2;
		System.out.println("*********");
		//则以下方法属性可以调用
		m1.earnMoney();
		m1.isSmoking=true;		
	}
}

但是使用强转时,可能出现ClassCastException异常
如图:

于是引入instanceof关键字:.
instanceof使用:
a instanceof A来判断对象a是否为类A的实例。如果是返回true,如果不是返回false。

完善PersonTest代码:

package com.atguigu.java3;
public class PersonTest {
	public static void main(String[] args) {
		Person p1=new Person();
		//引入多态性:父类的引用指向子类的对象
		Person p2=new Man();                  //注意new的p2是男的
		//多态性的使用:当调用子父类同名同参数的方法时,实际执行的是子类中重写父类的方法----------称为虚拟方法调用
		p2.eat();   //执行子类中重写父类的方法
		p2.walk();  //执行子类中重写父类的方法
		System.out.println("*********");
		//使用强转时,可能出现ClassCastException异常,为了避免异常,在向下转型之前先进行instanceof判断,true时再进行向下转型
		if(p2 instanceof Woman){    //关注p2是男还是女
			Woman w1=(Woman)p2;   //则强转
			w1.goShopping();
			System.out.println("*****Woman*******");
		}
		if(p2 instanceof Man){          
			Man m2=(Man)p2;   //则强转
			m2.earnMoney();
			System.out.println("*****Man*******");
		}
		//如果a instanceof A为true、类B是类A的父类,则a instanceof B也返回true
		if(p2 instanceof Person){
			System.out.println("*****Person*******");
		}
		if(p2 instanceof Object){
			System.out.println("*****Object*******");
		}
	}
}

总结:

多态练习:
练习1:

package com.atguigu.exer;

class base {
	int count = 10;
	public void display() {
		System.out.println(this.count);
		}
}
class Sub extends base {
	int count = 20;
	public void display() {
		System.out.println(this.count);
		}
}

public class FieldMethodTest {
	public static void main(String[] args){
		Sub s = new Sub();
		System.out.println(s.count);    //20
		s.display();  //20
		
		base b = s; //多态。子类对象赋给了父类引用
		System.out.println(b == s);  //true,地址一样,此处二者指向堆空间中的同一个对象。“==”对于引用数据类型比较的是地址值是否相同
		System.out.println(b.count);  //10。多态性不适用于属性
		//需要注意开发中我们尽量不要定义同名的属性
		b.display(); //20。虚拟方法调用
		}
}

总结:
练习2:

package com.atguigu.exer;

public class InstanceTest {
	public static void main(String[] args) {
		InstanceTest test=new InstanceTest();
		test.method(new Student());  
	}
	
	public void method(Person e){ //赋值过来,变成多态
		//虚拟方法调用
		String info = e.getInfo();
		System.out.println(info);
		//方式一:
		if(e instanceof Graduate){   //先写范围小的
			System.out.println("a graduated student");
			System.out.println("a student");
			System.out.println("a person");
		}else if(e instanceof Student){ //我们new的是Student,进入此分支
			System.out.println("a student");
			System.out.println("a person");	
		}else{
			System.out.println("a person");	
		}
		//方式二:(更简洁)
		
	}

}	
	
	
class Person {
	protected String name="person";
	protected int age=50;
	public String getInfo() {
		return "Name: "+ name + "n" +"age: "+ age;
	}
}
class Student extends Person {
	protected String school="pku";
	public String getInfo() {  //重写
		return "Name: "+ name + "nage: "+ age + "nschool: "+ school;
	}
}
class Graduate extends Student{
	public String major="IT";
	public String getInfo(){   //重写
		return "Name: "+ name + "nage: "+ age 
		+ "nschool: "+ school+"nmajor:"+major;
	}
}


练习3:
①GeometricObject

package com.atguigu.exer;

public class GeometricObject {    //几何图形
	protected String color;
	protected double weight;
		
	public GeometricObject(String color, double weight) {
		super();
		this.color = color;
		this.weight = weight;
	}
	
	public String getColor() {
		return color;
	}
	public void setColor(String color) {
		this.color = color;
	}
	public double getWeight() {
		return weight;
	}
	public void setWeight(double weight) {
		this.weight = weight;
	}
	
	public double findArea(){
		return 0.0;
	}
	
	
	
}

②Circle

package com.atguigu.exer;

public class Circle extends GeometricObject {
	private double radius;

	public Circle(double radius,String color, double weight) {
		super(color, weight);
		this.radius=radius;
	}

	public double getRadius() {
		return radius;
	}

	public void setRadius(double radius) {
		this.radius = radius;
	}
	
	public double findArea(){
		return 3.14*radius*radius;
	}
}

③MyRectangle

package com.atguigu.exer;

public class MyRectangle extends GeometricObject {
	private double width;
	private double height;
	
	public MyRectangle(double width,double height,String color, double weight) {
		super(color, weight);
		this.width=width;
		this.height=height;		
	}

	public double getWidth() {
		return width;
	}

	public void setWidth(double width) {
		this.width = width;
	}

	public double getHeight() {
		return height;
	}

	public void setHeight(double height) {
		this.height = height;
	}
	
	//重写findArea()
	@Override
	public double findArea() {
		return width*height;
	}
}
	

GeometricTest:

package com.atguigu.exer;

public class GeometricTest {
	public static void main(String[] args) {
		GeometricTest test=new GeometricTest();
		
		Circle c1=new Circle(2.3, "white", 1.0);
		test.displayGeometricObject(c1);   //实际调用时放的是Circle
		Circle c2=new Circle(3.3, "white", 1.0);
		test.displayGeometricObject(c2);
		
		boolean isEquals = test.equalsArea(c1, c2);
		System.out.println("c1和c2的面积是否相等:"+isEquals);
		
		MyRectangle rect=new MyRectangle(2.1, 3.4, "red", 2.0);
		test.displayGeometricObject(rect);
	}
	
	//displayGeometricObject方法显示对象的面积
	public void displayGeometricObject(GeometricObject o){      //多态性
		System.out.println("面积为:"+o.findArea());
	}
	//测试两个对象面积是否相等
	public boolean equalsArea(GeometricObject o1,GeometricObject o2){
		return o1.findArea()==o2.findArea();
	} 
	
}
 

面试题:
型一:

package com.atguigu.exer;
//考查多态的笔试题目:
public class InterviewTest1 {

	public static void main(String[] args) {
		base1 base = new Sub1();  //多态
		base.add(1, 2, 3);      //问题:此处输出什么内容? 答:输出“sub_1”    
	}
}

//父类
class base1 {
	public void add(int a, int... arr) {   //含可变个数的形参
		System.out.println("base");
	}
}
//子类
class Sub1 extends base1 {

	public void add(int a, int[] arr) {   //解题关键:此处认为是重写
		System.out.println("sub_1");
	}

//	public void add(int a, int b, int c) {   //若此处三行打开,输出结果不会变仍为“sub_1”
//		System.out.println("sub_2");  //此处不认为重写父类add方法(形参列表不同)
//	}

}


型二:

package com.atguigu.exer;
//考查多态的笔试题目:
public class InterviewTest1 {

	public static void main(String[] args) {
		base1 base = new Sub1();  //多态
		base.add(1, 2, 3);      //问题:输出什么内容? 输出“sub_2”

		Sub1 s = (Sub1)base;  //此处对base进行强转(向下转型)
		s.add(1,2,3);   // 输出   “sub_2”,因为确定参数个数的方法会优先调用
	}
}

//父类
class base1 {
	public void add(int a, int... arr) {   //可变形参
		System.out.println("base");
	}
}
//子类
class Sub1 extends base1 {

	public void add(int a, int[] arr) {   
		System.out.println("sub_1");
	}

	public void add(int a, int b, int c) {   
		System.out.println("sub_2");  
	}

}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/775506.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号