多态性
- 一个事物有多种形态
- 对象的多态性:父类的引用指向子类的对象
- 当调用子父类同名方法时,实际执行子类重写父类的方法(虚拟方法调用)
- 不能调用子类特有的方法,只能调用父类中的方法
- 使用前提是类的继承和方法重写
- 多态性只适用于方法,不适用于属性
- 示例:
public class AnimalTest {
public static void main(String[] args) {
AnimalTest animalTest=new AnimalTest();
animalTest.show(new dog());
}
public void show(Animal animal){
animal.walk();
animal.eat();
System.out.println(animal.kind);
}
}
class Animal{
String kind="未知";
public void eat(){
System.out.println("吃");
}
public void walk(){
System.out.println("跑或走");
}
}
class dog extends Animal{
String kind="dog";
public void eat(){
System.out.println("吃骨头");
}
public void shout(){
System.out.println("汪!汪!汪!");
}
}
虚拟方法调用(多态情况下)
- 子类中定义了父类同名参数的方法,在多态情况下,将此时父类的方法称为虚拟方法
- 父类根据赋给它子类不同,动态调用子类的方法,该方法在编译期无法确定
- 理解多态在编译时不确定,只有在运行时才确定
import java.util.Scanner;
public class AnimalEatTest {
public static void main(String[] args) {
AnimalEatTest animalEatTest=new AnimalEatTest();
Scanner scan=new Scanner(System.in);
System.out.print("输入0-2");
int index = scan.nextInt();
switch (index){
case 0:
animalEatTest.show(new dog());
break;
case 1:
animalEatTest.show(new cat());
break;
case 2:
animalEatTest.show(new cattle());
}
}
public void show(Animal animal){
animal.eat();
}
}
class Animal{
public void eat(){
System.out.println("吃");
}
}
class dog extends Animal{
public void eat(){
System.out.println("吃骨头");
}
}
class cat extends Animal{
public void eat(){
System.out.println("吃鱼");
}
}
class cattle extends Animal{
public void eat(){
System.out.println("吃草");
}
}
instanceof操作符
- 有了对象多态性后,内存中实际是加载了子类中声明的属性和方法,但由于声明的是父类类型,所以不能调用
- 使用子类特有的属性和方法需要向下转型使用强制类型转换(跟数据类型转换相似)
- 示例:
public class PersonTest {
public static void main(String[] args) {
Person p1=new Man();
p1.eat();
Man m1=(Man)p1;
m1.getMoney();
}
}
class Person{
public void eat(){
System.out.println("吃");
}
}
class Man extends Person{
public void eat(){
System.out.println("大口吃");
}
public void getMoney(){
System.out.println("挣钱");
}
}
- 当类型转换时可能出现异常ClassCastException(类型转换异常),可以通过instaceof判定是否可以强转
- 语法:a instaceof A (判断对象a是否是类A的实例)
- 示例:
public class PersonTest {
public static void main(String[] args) {
Person p1=new Man();
p1.eat();
if(p1 istanceof Man){
Man m1=(Man)p1;
m1.getMoney();
}
}
}
class Person{
public void eat(){
System.out.println("吃");
}
}
class Man extends Person{
public void eat(){
System.out.println("大口吃");
}
public void getMoney(){
System.out.println("挣钱");
}
}
Oject类的使用
- Object类是所有JAVA类的根父类,当类中没有extends指明其父类时,默认为java.lang.Object类
- Object没有属性,并只声明了一个空参构造器
- equals()方法
- Object类中equals()与 ==是相同的,都是比较对象地址值是否相同
- 但String,Date,File,包装类等重写了Object类中equals()方法,比较的两个对象实体内容是否相同
- 重写equals()
public class CustomerTest {
public static void main(String[] args) {
Person2 p1=new Person2("jack",20);
Person2 p2=new Person2("jack",20);
System.out.println(p1 == p2);
System.out.println(p1.equals(p2));
}
}
class Person2{
String name;
int age;
public Person2(String name,int age){
this.name=name;
this.age=age;
}
public boolean equals(Object object){
if(this == object){
return true;
}
if(object instanceof Person2){
Person2 p2=(Person2) object;
return this.age == p2.age && this.name.equals(p2.name);
}
return false;
}
}
toString()
- 当我们输出一个对象的引用时,实际上就是调用toString()方法
- String,Date,File,包装类等重写了Object类中toString()方法,使得在调用时返回"实体内容"
- 示例:
public class CustomerTest {
public static void main(String[] args) {
Person2 p1=new Person2("jack",20);
Person2 p2=new Person2("jack",20);
System.out.println(p2.toString());
}
}
class Person2{
String name;
int age;
public Person2(String name,int age){
this.name=name;
this.age=age;
}
public String toString(){
return "Person2[" + "name=" +name +"age=" +age +"]";
}
}