Java面向对象(多态,instanceof,类型转换,static 关键字)

多态


◆ 动态编译:类型:可扩展性

◆ 即同一方法可以根据发送对象的不同而采用多种不同的行为方式。

◆ 一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多(父类、有关系的类)

◆ 多态存在的条件

  • 有继承关系

  • 子类重写父类方法

  • 父类引用指向子类对象

◆ 注意:多态是方法的多态,属性没有多态性。

instanceof (类型转换)引用类型,判断一个对象是什么类型

  • 基础类型转换的高低关系:是指容量的大小
  • 引用类型转换:是指父类和子类
  • instanceof可以判断两个类之间是否存在父子关系,有父子关系就OK

多态存在条件

package com.oop;


import com.oop.demo05.A;
import com.oop.demo05.B;
import com.oop.demo06.Person;
import com.oop.demo06.Student;

public class Application {

    public static void main(String[] args) {

        //一个对象的实际类型是确定的
        //new Student();
        //new Person();

        //可以指向的引用类型就不确定了:父类的引用指向子类

        //Student 能调用的方法都是自己的或者继承父类的!
        Student s1 = new Student();
        //Person 父类型,可以指向子类,但是不能调用子类独有的方法
        Person s2 = new Student();
        Object s3 = new Student();


        s2.run();//子类重写了父类的方法,执行子类的方法
        s1.run();
        /*
        结果:son
             son
         */

        //对象能执行哪些方法,主要看对象左边的类型,和右边关系不大!
        ((Student) s2).eat();//s2.eat()强制转换
        s1.eat();

        /*
        Java里的方法调用,它是运行时和动态对象绑定的
        就像eat,他运行之前他并不知道执行了什么,他也不知道会被哪个方法调用
        因为我们之间可以存在类型之间的转换
         */

    }

}

package com.oop.demo06;

public class Student extends Person{

    @Override
    public void run() {
        System.out.println("son");
    }

    public void eat(){
        System.out.println("eat");
    }
}

package com.oop.demo06;

public class Person {

    public void run(){
        System.out.println("run");
    }

}

/*
多态注意事项:
    1. 多态是方法的多态,属性没有多态
    2. 父类和子类,有联系  否则会类型转换异常!(例如String 与 Object 就不可以) ClassCartException!
    3. 存在条件:继承关系,方法需要重写,父类引用指向子类对象! Father f1 = new Son();


不能重写的方法:
    1. static 方法,属于类,它不属于实例;
    2. final 常量(无法改变的,它是在常量池里的)
    3. private 方法
 */



instanceof

package com.oop;

import com.oop.demo06.Person;
import com.oop.demo06.Student;
import com.oop.demo06.Teacher;

public class Application {

    public static void main(String[] args) {

        //Object > String
        //Object > Person > Teacher
        //Object > Person > Student
        Object object = new Student();

        //System.out.println(X instanceof Y);//能不能编译通过,就取决于X和Y之间是否存在父子关系;
        //结果是true或者false ,X所指向的实例类型是Y的子类型,或者 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,Teacher是另一条线,跟Student无关,跟这个类型一点关系都没有
        System.out.println(object instanceof String);//false,String是 Object lang包下面的,更没关系了

        System.out.println("===================================");
        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);//编译报错!string和 person同级,它是两条线


        System.out.println("===================================");
        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);//false,编译报错!
                // instanceof是一个比较转换的过程,比较肯定是两边有关系的才会返回true或者false
        //System.out.println(student instanceof String);//false,编译报错! 两者没关系会直接报错
    }

    /*
    结果:
        true
        true
        true
        false
        false
        ===================================
        true
        true
        true
        false
        ===================================
        true
        true
        true

     */

}

package com.oop.demo06;

public class Student extends Person{

    public void go(){

    }

}

package com.oop.demo06;

public class Teacher extends Person{
}


package com.oop.demo06;

public class Person {

    public void run(){
        System.out.println("run");
    }

}



类型转换


package com.oop;

import com.oop.demo06.Person;
import com.oop.demo06.Student;
import com.oop.demo06.Teacher;

public class Application {

    public static void main(String[] args) {
        //类型之间的转化: 基本类型转换,满足高-->低需要强转(可能会丢失精度),低-->高则不需要强转 64/32/16/8位

        //类型之间的转化:父  子

        //高                    低
        Person obj = new Student();
        //student将这个对象转换为Student类型,我们就可以使用Student类型的方法了!
        //高 --> 低 :需要强制转换
        Student obj1 = (Student) obj;


        //子类转换为父类,可能丢失自己的本来的一些方法!
        Student student = new Student();
        student.go();
        Person person = student;
    }

    /*
    多态总结:
        1. 父类引用指向子类的对象(子类引用指向父类的对象肯定是不行的)
        2. 把子类转换为父类,也就是向上转型:不用强制转换;
        3. 把子类转换为父类,也就是向下转型:需要强制转换;(可能会丢失一些方法)
        4. 方便方法的调用,减少重复的代码!简洁

    抽象:封装、继承、多态!       抽象类,接口
     */

}



package com.oop.demo06;

public class Student extends Person{

    public void go(){
        System.out.println("go");
    }
}


package com.oop.demo06;

public class Teacher extends Person{
}


package com.oop.demo06;

public class Person {

    public void run(){
        System.out.println("run");
    }

}




static 关键字


静态属性

package com.oop.demo07;

//static
public class Student {

    private static int age;//静态的变量  多线程!
    private double score;//非静态的变量

    public static void main(String[] args) {
        Student s1 = new Student();
        

        System.out.println(Student.age);//类变量跟类中的所有实例共享
        //System.out.println(Student.score);这是不行的
        System.out.println(s1.age);
        System.out.println(s1.score);

    }

}

静态方法

package com.oop.demo07;

//static
public class Student {

    private static int age;//静态的变量  多线程!
    private double score;//非静态的变量

    public void run(){//非静态方法可以调用静态方法里的所有东西
        go();
    }

    public static void go(){//静态方法可以调用静态方法里的所有东西

    }

    public static void main(String[] args) {
        new Student().run();//对象.方法
        Student.go();
        go();

    }

}

静态代码块

package com.oop.demo07;

public class Person {

    //2:赋初值~
    {
        //代码块(匿名代码块)
        //没有名字,程序不会主动调用这些模块
        //匿名代码块:创建对象时就自动创建了,而且在构造器之前
        System.out.println("匿名代码块");
    }

    //1 : 只执行一次~
    static {
        //静态代码块
        //可以在里面加载一些初始化的数据
        //静态代码块:类一加载就直接执行,永久只执行一次
        System.out.println("静态代码块");
    }

    //3
    public Person(){
        System.out.println("构造方法");
    }

    public static void main(String[] args) {
        Person person1 = new Person();
        System.out.println("=================");
        Person person2 = new Person();
    }

    /*
        结果:
            静态代码块
            匿名代码块
            构造方法
            =================
            匿名代码块
            构造方法
     */
}

package的一些新特性

package com.oop.demo07;

//静态导入包~
import static java.lang.Math.random;
import static java.lang.Math.PI;

public class Test {

    public static void main(String[] args) {
        System.out.println(random());
        System.out.println(PI);
    }

    /*
    final 通过final修饰的类不能被继承,就没有子类
     */
}

上一篇:JAVA多态


下一篇:【复习回顾】instanceof和总结