多态性:即对象的多态性,父类的声明指向子类的对象。比如存在一个Father类和它的子类Son类,语句Father f = new Son(); 即对象的多态。
使用(虚拟方法的调用):在编译时,只能调用父类中声明过的方法,在运行时,实际执行的是子类重写父类的方法。
使用前提:类的继承、方法的重写。
只适用于方法,不适用于属性(多态是运行时行为)
一、向下转型的使用
当使用对象的多态性后,内存中实际是加载了子类所特有的方法和属性,但由于声明为父类类型,所以编译时只能调用父类的属性和方法,无法调用子类所特有的属性和方法。
1、使用向下转型来调用子类所特有的方法和属性
//Son继承Father类 eat() walk()是父类中的方法 play()是子类所特有的方法
Father father = new Son(); //多态的体现
father.eat(); //实际调用的是子类重写父类的方法
Son son1 = (Son)father; //向下强制转型来调用子类所特有的属性和方法
son1.play(); //子类方法
2、instanceof关键字的使用
a instanceof A : 判断对象a是否是类A的实例化,是返回true,否返回false,防止在进行向下转型抛出ClassCastException异常,可以在转型前先利用instanceof判断。
如果a instanceof A返回true,则a insatnceof B也返回true(B是A的父类)
Father father = new Son(); //多态的体现
father.eat(); //实际调用的是子类重写父类的方法
Son son = new Son();
Son son1 = (Son)father; //向下强制转型来调用子类所特有的属性和方法
if(son1 instanceof Son){ //判断son1是否是Son的实例
son1.play(); //调用子类特有属性或方法
}
if (son1 instanceof Father){ //返回true
System.out.println("yeah");
}
3、练习
代码如下:
public class GeometricTest {
public static void main(String[] args) {
GeometricTest gT = new GeometricTest();
Circle c1 = new Circle("red",1.0,4.0);
Circle c2 = new Circle("red",1.0,5.0);
MyRectangle myRectangle = new MyRectangle("red",2.0,3.0,4.0);
System.out.println("The two object's area is similar? " + gT.equalsArea(c1,c2));
gT.displayGeometricObject(c1);
gT.displayGeometricObject(myRectangle);
}
public boolean equalsArea(GeometricObject object1, GeometricObject object2){
return object1.findArea() == object2.findArea();
}
public void displayGeometricObject(GeometricObject object){
System.out.println("The object's area is: "+ object.findArea());
}
}
//GeometricObject类
class GeometricObject{
protected String color;
protected double weight;
public GeometricObject(String color, double weight) {
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类
class Circle extends GeometricObject{
private double radius;
public Circle(String color, double weight, double radius) {
super(color, weight);
this.radius = radius;
}
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
public double findArea(){
return Math.PI*radius*radius;
}
}
//MyRectangle类
class MyRectangle extends GeometricObject{
private double width;
private double height;
public MyRectangle(String color, double weight, double width, double height) {
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;
}
public double findArea(){
return width*height;
}
}
二、Object类
Object是Java所有类的根父类,如果类没有使用extends指明其父类,则默认其父类为java.lang.Object,Object类中只声明了一个空参构造器。
1、equals()方法
(1) 问:”==“与“equals”的区别?
”==“:是一个运算符;可以用在基本数据类型和引用中;如果用在基本数据类型中,比较两个变量保存的值是否相同(类型不一定要一样);如果比较的是引用数据类型变量,比较两个变量的地址值是否相同,即两个引用是否指向同一个对象实体。
char c1 = 'a';
int c2 = 97;
System.out.println(c1==c2); //true 比较值是否相同 类型不一定要一样
“equals”:是一个方法;只能用于引用数据类型;Object类中equals()方法的定义与"=="相同,都是比较两个变量的地址值是否相同;String、Date、File、包装类都重写了Object类中的equals()方法,比较的是两个对象的"实体内容"是否相同;自定义的类使用equals()方法也是比较两个对象的“实体内容”是否相同,需要对Object类中的equals()重写
public class Test {
public static void main(String[] args) {
String str1 = new String("helloworld");
String str2 = new String("helloworld");
System.out.println(str1.equals(str2)); //true String重写了equals()方法 比较实体内容
Person person = new Person();
Person person1 = new Person();
System.out.println(person.equals(person1)); //false 比较两个变量所指向的地址值是否相同
}
}
(2) 练习题
代码如下:
import to_object.constructor.Person;
public class Test {
public static void main(String[] args) {
Order order1 = new Order(1001,"zhang");
Order order2 = new Order(1001,"zhang");
Order order3 = new Order(1002,"chen");
System.out.println(order1.equals(order2)); //true
System.out.println(order1.equals(order3)); //false
}
}
class Order{
private int orderId;
private String orderName;
public Order(int orderId, String orderName) {
this.orderId = orderId;
this.orderName = orderName;
}
public int getOrderId() {
return orderId;
}
public void setOrderId(int orderId) {
this.orderId = orderId;
}
public String getOrderName() {
return orderName;
}
public void setOrderName(String orderName) {
this.orderName = orderName;
}
public boolean equals(Object obj){
if (obj == this){ //如果两个对象地址值相同直接返回true
return true;
}
if (obj instanceof Order){ //判断是否是Order的实例
//向下转型 使可以调用子类所特有的方法(不然只能调用被重写的方法)
Order order = (Order)obj; //将传进来的对象强转为Order型 则可以调用Order类的相关属性与方法
return this.orderId == order.orderId && this.orderName == order.orderName;
}
return false;
}
}
2、toString()方法的使用
当我们输出一个对象的引用时,实际上是调用该对象的toString()方法,String、Date、File、包装类都重写了Object类中的equals()方法,于是在调用toString()方法时,返回该对象实体的内容。
(1)练习题
代码如下:
public class Test {
public static void main(String[] args) {
Circle circle1 = new Circle(3.0);
Circle circle2 = new Circle("red",2.0,2.0);
System.out.println("颜色是否相同: " +
circle1.getColor().equals(circle2.getColor())); //false
System.out.println("半径是否相同: " + circle1.equals(circle2)); //false
System.out.println("the radius is: " + circle1.toString());
}
}
class GeometricObject{
protected String color;
protected double weight;
public GeometricObject() {
this.color = "white";
this.weight = 1.0;
}
public GeometricObject(String color, double weight) {
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;
}
}
class Circle extends GeometricObject{
private double radius;
public Circle(){
super();
color = "white";
}
public Circle(double radius) {
super();
this.radius = radius;
}
public Circle(String color, double weight, double radius) {
super(color, weight);
this.radius = radius;
}
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
public double findArea(){
return Math.PI*radius*radius;
}
//重写equals()方法判断半径是否相等
public boolean equals(Object obj){
if (obj == this){
return true;
}
if (obj instanceof Circle){
Circle circle = (Circle)obj;
return this.radius == circle.radius;
}
return false;
}
//重写toString()方法
@Override
public String toString() {
return "Circle{" + "radius=" + radius + '}';
}
}
三、包装类
1、基本数据类型、包装类与String之间的转换
(1)基本数据类型-->包装类
//基本数据类型转化为包装类:调用包装类的构造器
int num = 10;
Integer in1 = Integer.valueOf(num); //将num包装起来
Integer in2 = Integer.valueOf("10");
System.out.println(in2.toString()); //10 toString()方法被重写过 输出实体内容的值
Float f1 = Float.valueOf(12.7f);
Float f2 = Float.valueOf("12.7");
Boolean b = Boolean.valueOf(true);
Boolean b1 = Boolean.valueOf("false");
(2)包装类-->基本数据类型
//包装类转化为基本数据类型:调用包装类的***Value()
Integer integer = Integer.valueOf(12);
int in3 = integer.intValue();
Float f3 = Float.valueOf(14.0f);
float f4 = f3.floatValue();
(3)基本数据类型、包装类-->String
//方式一:连接
int n = 20;
String str = 20 + "";
System.out.println(str instanceof String); //true
//方式二:调用String的valueOf()方法
int n1 = 30;
Double d1 = Double.valueOf(12.6);
String str1 = String.valueOf(n1); //基本数据类型转String类型
String str2 = String.valueOf(d1); //包装类转String类型
System.out.println(str1 instanceof String); //true
System.out.println(str2 instanceof String); //true
(4) String-->基本数据类型、包装类
//调用包装类的parseInt(String str)方法
String str3 = "123";
int n2 = Integer.parseInt(str3);
System.out.println(n2); //123
String str4 = "false";
boolean b = Boolean.parseBoolean(str4);
(5)自动装箱与拆箱
//自动装箱与拆箱
public void test2() {
int num2 = 30;
//自动装箱 直接将int变量num2赋给一个形参为对象的方法
method(num2);
//自动拆箱 直接将对象in2赋给一个基本数据类型的变量
System.out.println("------------------------");
Integer in2 = 3; //in2是一个对象
System.out.println(in2 instanceof Object); //true
int in3 = in2;
System.out.println("------------------------");
}
2、练习题
import java.util.Scanner;
import java.util.Vector;
import java.util.logging.Level;
public class VectorTest {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
//创建Vector对象
Vector vector = new Vector();
//定义最高分数
int maxScore = 0;
char level;
//循环读取学生成绩
for (;;){
System.out.println("please input the students' score: ");
//从键盘读取分数
int score = scan.nextInt();
//当分数为负数退出循环
if (score < 0){
break;
}
if (score > 100){
System.out.println("The score that you input is out of the boundary");
continue;
}
//向vector对象中添加score
vector.addElement(score); //自动装箱 score是一个int型变量 而addElement(Object obj)
//求最高分
if (maxScore < score){
maxScore = score;
}
}
//循环输出学生成绩与等级 vector.size()获取向量长度
for (int i = 0; i < vector.size(); i++){
Object obj = vector.elementAt(i); //vector.elementAt(i)取出向量中的元素 为对象类型
//强转为int型类型
int score1 = (int)obj;
if ((maxScore - score1) <= 10){
level = 'A';
}
else if ((maxScore - score1) <= 20){
level = 'B';
}
else if ((maxScore - score1) <= 30){
level = 'C';
}
else {
level = 'D';
}
System.out.println("The students' score is: " + score1 + ",the level of it is: " + level);
}
}
}