面向对象06[instanceof和类型转换、static关键字详解、抽象类]

instanceof和类型转换

(需要掌握的点全在代码里)


instanceof

instanceof是Java、php的一个二元操作运算符,和==,>,<是同一类东西。由于它是由字母组成的,所以也是Java的保留关键字。它的作用是判断其左边对象是否为其右边类的实例,返回boolean类型的数据。

用法:boolean result = object instanceof class

参数
result:布尔类型
object:必选项 任意对象表达式。
class:必选项 任意已定义的对象的类

说明:如果object是class的一个实例,则其返回值为true;如果object不是指定类的一个实例,或者object是null,则返回false。

关于instanceof的东西都放在启动类里,不分开写了,不然查看起来不方便.
public class Application {
    public static void main(String[] args) {
   		//Object > Person > Student
        //两边必须要有关联,否则直接编译报错(两者不一定是子父关系,但必须有关联,即可以是同级关系)
        //System.out.println(X instanceof Y); 判断引用X指向的实际类型是不是Y的子类型,是true,不是false
        
        Object object = new Student();
        //true
        System.out.println(object instanceof Student);
        //true
        System.out.println(object instanceof Person);
        //true
        System.out.println(object instanceof Object);
        //false
        System.out.println(object instanceof Teacher);
        //false
        System.out.println(object instanceof String);
        System.out.println("========================");
        Person person = new Student();
        //true
        System.out.println(person instanceof Student);
        //true
        System.out.println(person instanceof Person);
        //true
        System.out.println(person instanceof Object);
        //false
        System.out.println(person instanceof Teacher);
        //编译报错
        //System.out.println(person instanceof String);
        System.out.println("==========================");
        Student student = new Student();
        //true
        System.out.println(student instanceof Student);
        //true
        System.out.println(student instanceof Person);
        //true
        System.out.println(student instanceof Object);
        //编译报错
        //System.out.println(student instanceof Teacher);
        //编译报错
        //System.out.println(student instanceof String);

		public class Person {
    		public void run(){
        		System.out.println("run");
    		}
		}
		public class Student extends Person{
    		public void go(){
        		System.out.println("go");
    		}
		}
		public class Teacher extends Person{
		}
    }
}

instanceof:
1.两边必须要有关系,否则直接编译报错(两者不一定是子父关系,但必须有关联,即可以是同级关系)
2.System.out.println(X instanceof Y); 判断引用X指向的实际类型是不是Y的子类型,是true,不是false

类型转换

1.启动类

public class Application {
    public static void main(String[] args) {
        //类型之间的转换:父  子
        //高         低    低转高,自动转换	向上转型
        Person obj = new Student();

        //高转低,强制转换	向下转型
        //将obj这个对象转换为Student类型,我们就可以使用Student类型的方法了
        ((Student) obj).go();

        //子类转换为父类,可能会丢失自己本来的一些方法!(除重写以外的所有方法)
        Student student = new Student();
        Person person = student;
        //person.go();
        //重写方法run
        person.run(); 
    }
}

2.父类Person

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

3.子类Student

public class Student extends Person{
    public void go(){
        System.out.println("go");
    }

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

4.子类Teacher

public class Teacher extends Person{
}

static关键字

关于static继承里面的问题,最近一直在讲就不在这再赘述了,想不起来就看前面博客

1.静态修饰符static(有关属性和方法问题)

public class Student {
    /**
     * 静态的实例变量
     * 一个静态实例变量对于这个类而言,只有这一个,它能被类中的所有实例去共享!(先做了解,多线程会再详细的去讲)
     * 当我们需要很多类操作一个实例变量时,我们都会选择static关键词去修饰
     */
    private static int age;
    /**
     * 非静态的实例变量
     */
    private double score;

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

    public static void main(String[] args) {
        Student stu = new Student();
        //若只写stu.score,只是调到了,但没有接收或输出它,是无意义的!
        //Student.score是不可以的    不能从静态上下文引用非静态字段“分数”
        //stu.score      非静态变量score必须通过实例化的对象来调!
        double score = stu.score;
        System.out.println(score);
        //System.out.println(stu.score);    将调用的打印输出

        //若只写Student.age,同样也只是调到了,但没有接收或输出它,无意义!
        //Student.age     静态变量age,通过类名Student来调
        int age = Student.age;
        System.out.println(age);
        //System.out.println(Student.age);    将调用的打印输出


        //静态方法直接调用,而同一类中,可省略类名
        sleep();
        //非静态方法必须首先创建类的对象,然后用其对象去调用
        stu.run();
        /*之前有说过,静态方法和类一起加载,在加载的时候还没有非静态方法,有调无,所以没法调!
        类加载顺序的问题,后面在注解与反射的时候会讲类加载机制,到时候要认真听、吸收和思考,就理解了*/
    }
}

2.静态修饰符static(静态代码块问题)

public class Person {
    //第二步执行
    {
        System.out.println("匿名代码块");
        //代码块(匿名代码块)   没有名字,程序在执行的时候并不能主动调用这些模块!
        //它是创建这个对象的时候它就自动创建了,而且它在构造器之前!     可以用这一特点进行 赋初始值操作
    }
    //第一步执行
    static {
        System.out.println("静态代码块");
        //静态代码块     跟类一加载,它就直接执行,整个过程只执行一次!
    }
    /**
     * 第三步执行
     */
    public Person() {
        System.out.println("构造方法");
    }

    public static void main(String[] args) {
        Person person1 = new Person();
        //通过输出等号分割线,来验证静态代码块在整个过程中只执行一次
        System.out.println("==============");
        Person person2 = new Person();
    }
}

3.静态导入包

package com.oop.demo11;

//静态导入包
import static java.lang.Math.random;
import static java.lang.Math.PI;
/**
 * @author 1301450090@qq.com
 * @date 2021/4/7 1:12
 */
public class Test {
    public static void main(String[] args) {
        //Math.random()   产生随机数的方法
        //System.out.println(Math.random());  通过静态导入包,我们这里的Math是可以省略的
        System.out.println(random());
        System.out.println(PI);
    }
}
/*
 * 一般没人这么去玩,讲静态导入包的目的是让我们明白,Java中的知识很多,只要你想学能学的东西太多啦!
 * 不要学了点循环就以为自己了不得,不要做愚昧山峰最顶端的人,拒绝当巨婴,拒绝浮躁!!!
 * 如果一个类被final修饰了,就没办法使其派生出子类了(final之后就断子绝孙啦--哈哈哈哈哈哈哈😄狂神说的)
 */

抽象类

关于抽象类,理解掌握以下内容就够了。由于类只能单继承,因此它不是我们的重点,重点是我们更多使用的接口(可以实现多继承)(紧接着后面会学)。

abstract修饰符可以用来修饰方法也可以修饰类,如果修饰方法,那么该方法就是抽象方法;如果修饰类,那么该类就是抽象类。
抽象类中可以没有抽象方法,但是有抽象方法的类一定要声明为抽象类。
抽象类,不能使用new关键字来创建对象,它是用来让子类继承的。
抽象方法,只有方法的声明,没有方法的实现,它是用来让子类实现的。
子类继承抽象类,那么就必须要实现抽象类没有实现的抽象方法,否则该子类也要声明为抽象类。

1.抽象类Action

package com.oop.demo12;

/**
 * @author 1301450090@qq.com
 * @date 2021/4/7 15:00
 * 抽象类   被abstract修饰的类
 * 在Java中,类只有单继承!      接口可以实现多继承!(后面要学,先做了解。)
 * 举个栗子:将接口看作是“插座”,它只约束了插什么插头,但是并没有约束什么电器才能插上去
 */
public abstract class Action {
    /**
     * 约束---希望有人可以帮我们实现
     * 被abstract修饰的方法,抽象方法,只有方法名字,没有方法的实现
     */
    public abstract void doSomething();

    //1.不能new这个抽象类,只能靠子类去实现它  它就是一个约束!
    //2.抽象方法必须存在于抽象类中,但是抽象类中可以写有非抽象(普通)方法

    //思考:抽象方法不能使用new关键字,那么它存在构造器吗?抽象类存在的意义是什么?
}

2.子类A

package com.oop.demo12;

/**
 * @author 1301450090@qq.com
 * @date 2021/4/7 15:06
 * 对于抽象类而言,继承了它的子类,都必须要实现它的所有方法    除非将子类也用abstract修饰
 */
public class A extends Action{
    @Override
    public void doSomething() {

    }
}
/*
若直接让A类仅去继承抽象类Action,而不做任何操作,则会编译报错
Class 'A' must either be declared abstract or implement abstract method 'doSomething()' in 'Action'

2.类"A"必须被声明为抽象
public abstract class A extends Action{
}

1.或者必须在"Action"中实现抽象方法"doSomething()"
我们通过方法重写来实现
 */

如果我的博客对你有一点点帮助,望请大侠可以给文章点个赞再走~
声明:因个人能力有限,博文中必有不足之处,望学术同仁不吝赐教!一起学习一起进步!
以上内容均为原创,转载请注明出处!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值