Java学习Day21
多态
多态的含义
同一方法可以根据发送对象的不同而采用多种不同的行为方式。
一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多(父类,有关系的类)
多态存在的条件
- 有继承关系
- 子类重写父类的方法
- 父类引用指向子类对象
Father f1 = new Son();
//父类
public class Person {
public void run(){
System.out.println("run");
}
}
//子类
public class Student extends Person{
public void run(){
System.out.println("son");
}
public void test(){
System.out.println("Student.test");
}
}
//测试类
public class Application {
public static void main(String[] args) {
//一个对象的实际类型是确定的
new Person();
new Student();
//但可以指向的引用类型不确定,父类引用可以指向子类对象
Student s1 = new Student();
Person s2 = new Student();
Object s3 = new Student();
//子类重写父类方法之后,运行同一个方法,父类引用会执行子类方法
s1.run();//son
s2.run();//son
//对象能执行哪些方法,主要看左边的类型,与右边关系不大!
//s2.test();会报错
s1.test();
((Student) s2).test();//父类想调用子类独有的方法需要进行类型强制转换
}
}
注意:
- 多态是方法的多态,属性没有多态
- 如果两个类没有继承关系 ,则会抛出异常ClassCastException
instanceof 关键字
判断对象和一个类是否有继承关系,一个对象是不是某一个类的实例
//测试类
public class Application {
public static void main(String[] args) {
//Student stu = new Person();报错 子类引用不可以指向父类对象,所以引用的范围一定大于实际对象的范围
//继承关系
//Object > String
//Object > Person > Teacher
//Object > Person > Student
Object o = new Student();
System.out.println(o instanceof Object);//true
System.out.println(o instanceof Person);//true
System.out.println(o instanceof Student);//true
System.out.println(o instanceof Teacher);//false
System.out.println(o instanceof String);//false
System.out.println("=================================");
Person p = new Student();
System.out.println(p instanceof Object);//true
System.out.println(p instanceof Person);//true
System.out.println(p instanceof Student);//true
System.out.println(p instanceof Teacher);//false
// System.out.println(p instanceof String); 报错
System.out.println("=================================");
Student s = new Student();
System.out.println(s instanceof Object);//true
System.out.println(s instanceof Person);//true
System.out.println(s instanceof Student);//true
// System.out.println(s instanceof Teacher); 报错
// System.out.println(s instanceof String); 报错
System.out.println("=================================");
}
}
结论:
- 判断报不报错:如果instanceof前面的变量的引用类型与instanceof后面的类有继承关系,则不报错,否则报错
- 判断true或false:如果instanceof前面的变量的new的对象类型是instanceof后面的类的子类,则是true,否则false
引用类型的转换
子类转父类:向上转型,可以自动转换
父类转子类:向下转型,需要强制转换
//测试类
public class Application {
public static void main(String[] args) {
//类型之间的转换:父类 子类
Student student = new Student();
student.test();
Person person = student;//子类转父类,自动转换,会丢失子类的一些独有的方法
// person.test(); 报错
Student student1 = (Student) person;//父类转子类,强制转换
}
}
多态的意义:方便方法的调用,减少重复的代码
static关键字
static修饰的属性或方法和类一起加载
public class Person {
//2.赋初始值
{
System.out.println("匿名代码块");
}
//1.只执行一次
static {
System.out.println("静态代码块");
}
//3
public Person() {
System.out.println("构造方法");
}
public static void main(String[] args) {
new Person();
/*
静态代码块
匿名代码块
构造方法
*/
System.out.println("==========================");
new Person();
/*
匿名代码块
构造方法
*/
}
}
static可以用于静态导入包
import static java.lang.Math.PI;
import static java.lang.Math.random;
public class Person {
public static void main(String[] args) {
System.out.println(random());//静态导入包后其中的方法随类一起加载,所以可以直接使用
System.out.println(PI);
}
}