多态
// 对象能执行什么方法,主要看对象左边的类型,和右边的没有关系
多态:同一方法可以根据发送对象的不同而采用不同的行为方式
父类:
public class Person
{public void run(){System.out.println("Person => run");}}
子类:
public class Student extends Person{@Overridepublic void run() {System.out.println("Student => run");}public void eat(){System.out.println("Student => eat");}
}
test.java
public class test {public static void main(String[] args) {// 一个对象的实际类型是确定的(左边)// 指向的引用类型不确定Person s1 = new Person();// 父类的引用 指向子类Person s2 = new Student();// 对象能执行什么方法,主要看对象左边的类型,和右边的没有关系s2.run();s2.eat();}
}
IDEA可以把s2强制转换为Student
4. 多态存在的条件
存在继承关系
子类重写父类
父类的引用,指向子类:Person person = new Student();
不能多态的情况:
static方法: 属于类的方法
final方法: 最终的,不能被继承重写
private方法: 私有的
5. instance判断是不是类的对象
用于判断对象的运行类型,是否是某个类的类型或者其子类型
// Object>Person>StudentStudent student = new Student();System.out.println(student instanceof Student); // trueSystem.out.println(student instanceof Person); // trueSystem.out.println(student instanceof Object); // true//System.out.println(student instanceof String); // 报错了Person person = new Student();System.out.println(person instanceof Student); // !! true!!System.out.println(person instanceof Person); // trueSystem.out.println(person instanceof Object); // trueObject object = new Student();System.out.println(object instanceof String); // falseString string = new String();System.out.println(string instanceof Object); // !! true
6. 类型转换
父类型引用指向子类型,无法调用子类型的方法,这时将对象强制转换为子类型
((Student) person).eat();
向上转型upcasting:子类对象赋值给父类引用,Father father = new Son();
向下转型downcasting:指向子类对象的父类引用,赋值给子类引用, Son son = (Son)father,这个father就是上面提到的那个father
Tip: 写方法时,父类作为参数,传入子类对象,就是利用了向上转型。这时子类自己的方法不好使,重写了父类的方法的可以用,父类的方法也可以用。
修饰符
static
静态变量属于类,在创建类时分配内存,各对象共享static类变量
非静态变量属于对象,在创建对象时分配内存,对象间不共享
public static void main(String[] args) {/*Person <- StudentPerson <- TeacherPerson中有static变量nameStudent和Teacher中各自有一个变量Age*/// s2改变了s1的name,因为name是共享的static变量Person s1 = new Student();s1.setName("s1");System.out.println(s1.name); // s1Person s2 = new Teacher();s2.setName("s2");System.out.println(s1.name); // s2//s2设置的Age值不会影响到s1,因为是各自的变量,不是类共享的((Student) s1).setAge(3);System.out.println(((Student)s1).getAge()); //3((Teacher) s2).setAge(4);System.out.println(((Teacher)s2).getAge());// 4((Student) s1).setAge(3);System.out.println(((Student)s1).getAge());//3}
final
修饰类:该类不能被继承
修饰方法:该方法可以被继承,但继承后不能被重写
修饰变量
局部变量:
如果是形参设为final则不能在方法体中赋值,因为已经在传参时赋过一次了。
如果是函数体中的局部变量,只能赋值一次,不能多次赋值
非静态成员变量:声明时赋值; 匿名代码块赋值; 构造器中赋值【可以把声明时赋值和在代码块中赋值理解成一个,都是声明时赋值,写法不一样罢了】
// 声明时赋值private final int b = 1;// 匿名代码块赋值{final int d = 5;}// 构造器赋值private final int a;public Person(int a) {this.a = a;}
静态成员变量:声明时赋值; 静态代码块赋值
// 静态成员变量:不能在构造器中赋值,声明时赋值private static final int b = 0;// 或者用“静态代码块”,也是声明时赋值static{int b = 1;int c = 2;}
引用变量:正常使用 就是不能再重赋值了
abstract