1.Static关键字详解
1.静态的变量对于这个类而言,在内存中只有一个,它能被类中所有的实例去共享。所以我们想要很多类去操作它的话我们就用static。在多线程里面会仔细用到.
2.静态变量对于类、所有对象(实例)是共享的,在当前这个类里面,当使用类去调用得到说明这个变量是静态的。
3.通过(类名.变量)知道它是一个静态的变量
4.非静态的方法可以直接访问这个类中的静态方法
5.静态方法只能调用静态方法,不能调用非静态的方法。main方法也是一个static静态的。
public class Student {
public static int age; /*静态的变量 静态变量对于类、所有对象(实例)是共享的,在当前这个类里面,当使用类去调用得到说明这个变量是静态的。*/
public double score; //非静态的变量
public void run(){//非静态方法
go(); //非静态的方法可以直接访问这个类中的静态方法
}
public static void go(){ //静态方法
}
public static void main(String[] args) {
System.out.println(Student.age); /* 0 类变量,通过(类名.变量)知道它是一个静态的变量 */
//System.out.println(Student.score); 非静态字段,不能这样子去用
Student s1 = new Student(); //new一个对象。(对象.变量) 是一个非静态的变量
System.out.println(s1.age); //0
System.out.println(s1.score); //0.0
Student.go();
// 直接调用go方法(类名.方法) 或者不用Student直接写:go(); 因为它在类里面。
/*静态方法只能调用静态方法,不能调用非静态的方法。main方法也是一个static。不能直接写run();*/
new Student().run(); //通过(对象.方法)来调用run方法。不能直接调用run方法
}
}
代码块
1.静态代码块 : 和类一加载就直接执行,最早加载、永久只执行一次。
2.匿名代码块: 程序在执行的时候并不能主动的去调用这些模块,创建对象的时候自动就建立了,而且在构造器之前。(可以赋初始值,和对象同时产生,在构造方法之前)
3.顺序为:静态代码块(和类一块加载)>匿名代码块>构造方法。
public class Person {
/*
{
//代码块(匿名代码块): 程序在执行的时候并不能主动的去调用这些模块,创建对象的时候自动就建立了,而且在构造器之前
}
static {
//静态代码块 : 和类一加载就直接执行,永久只执行一次
}
*/
{
System.out.println("匿名代码块"); //2.匿名代码块 可以赋初始值
}
static {//最早加载、只执行一次
System.out.println("静态代码块"); //1.静态代码块
}
public Person() { //构造器
System.out.println("构造方法"); //3.构造方法
}
public static void main(String[] args) {
System.out.println("===============");
Person person1 = new Person();
System.out.println("===============");
Person person2 = new Person();
}
/*
静态代码块
===============
匿名代码块
构造方法
===============
匿名代码块
构造方法
*/
}
//静态导入包
import static java.lang.Math.PI;
import static java.lang.Math.random;
public class Test {
public static void main(String[] args) {
System.out.println(random()); //可以不用写Math. Math.random()
System.out.println(PI);
}
}
final特性
通过final修饰的类就不能被继承,也就没有子类了
2.instanceof关键字
public class Person {
}
public class Student extends Person{
}
public class Teacher extends Person{
}
import com.oop.demo07.Student;
import com.oop.demo07.Person;
import com.oop.demo07.Teacher;
public class Application {
public static void main(String[] args) {
//Object>String
//Object>Person>Student
//Object>Person>Teacher
Object object = new Student();
// System.out.println(X instanceof Y); 能否编译通过! X与Y是否存在父子关系
//结果是true还是false:看变量X所指向的实际类型是不是Y的子类型
System.out.println(object instanceof Student); //true
System.out.println(object instanceof Person); //true
System.out.println(object instanceof Object); //true
System.out.println(object instanceof Teacher); //false
System.out.println(object instanceof String); //false
Person person = new Student();
System.out.println(person instanceof Student); //true
System.out.println(person instanceof Person); //true
System.out.println(person instanceof Object); //true
System.out.println(person instanceof Teacher); //false
// System.out.println(person instanceof String); //编译报错
Student student = new Student();
System.out.println(student instanceof Student); //true
System.out.println(student instanceof Person); //true
System.out.println(student instanceof Object); //true
// System.out.println(student instanceof Teacher); //编译报错
// System.out.println(student instanceof String); //编译报错
}
}
3.类型转换
类型之间的转化:父 子
1.父类引用指向子类的对象
2.把子类转换为父类:向上转型,直接转,丢失子类中原本可直接调用的特有方法,但如果是继承过来的仍然能调用。
3.把父类转换为子类:向下转型,强制转,丢失父类被子类所重写的掉的方法
4.方便方法的调用(不用重新new一个类,把它降级或者升级就可以调用它的一些其他的方法),减少重复的代码!简洁
public class Person {
public void run(){
System.out.println("run");
}
}
public class Student extends Person{
public void go(){
System.out.println("go");
}
}
import com.oop.demo07.Student;
import com.oop.demo07.Person;
import com.oop.demo07.Teacher;
public class Application {
public static void main(String[] args) {
//类型之间的转换 : 父 子
//高 低 低转高
Person obj = new Student();
//将student这个对选哪个转换为Student类型,我们就可以使用Student类型的方法了!
Student student = (Student) obj; //或者这两行写成一句话:((Student) obj).go();
student.go(); // go
Student student1 = new Student();
student1.go(); //go
Person person = student;//子类转换为父类,可能丢失自己的本来的一些方法!
//person.go(); 走不了go方法了
}
}