面向对象3(final、static、instanceof、向上/向下转型、初始化次序)

1. final

  • 对于基本类型,final 使数值不变;
  • 对于引用类型,final 使引用不变,也就不能引用其它对象,但是被引用的对象本身是可以修改的。

可用来修饰类、类的成员、局部变量:

  • final修饰的类——不可以被继承,但可以继承其他类
  • final修饰的方法——不可以被重写。但若父类中没有final修饰的方法,子类重写后,可加final修饰
    • private 方法隐式地被指定为 final
  • final修饰的变量——成为常量,只可被赋值一次。
    • 变量为:引用类型——变量值为对象的地址,地址值不可更改,但是地址内的对象属性值可以更改
    • 变量为:成员变量——需在创建的时候赋值,否则报错。(当未显式赋值时,多个构造方法内部均需为其赋值)。

2. static

一般用来修饰类中的成员。

被static修饰的成员属于这个类,不属于这个类的某个实例对象,可通过类名直接访问。

多个对象共享一个static成员变量。

实例变量:每创建一个实例就会产生一个实例变量,它与该实例同生共死。)

静态内容优先于对象存在,只能访问静态,不能使用this/super(没有对象,则无this)。

同一个类中,静态成员只能访问静态成员方法/变量。

main()为静态方法,仅仅为程序入口,它不属于任何一个对象,可以定义在任何类中。

2.1 静态变量

又称为类变量,也就是说这个变量属于类的。

静态变量属于类,只要静态变量所在的类被加载,这个静态变量就会被分配空间,在内存中只有一份,所有对象共享这个静态变量。

实例变量属于对象,只有对象被创建之后,实例变量才会被分配空间,才能被使用,它在内存中有多个复制。

使用有二种方式: 一个是类名.静态变量,还有一种是对象.静态变量。

特别注意:Java中不能在方法体中定义静态变量(无论该方法是静态的或是非静态的)。

2.2 静态方法

静态方法在类加载的时候就存在了,它不依赖于任何实例。

静态方法必须有实现,也就是说它不能是抽象方法(abstract) 。

只能访问所属类的静态字段和静态方法,方法中不能有 this 和 super 关键字。

重要用途:实现单例模式。

单例模式的特点:该类只有一个实例。需要求:

  1. 隐藏类的构造函数(构造函数声明为private);
  2. 提供一个创建对象的方法,通过该类的方法来获取类的对象(将这个方法声明为static)。
public class Singleton {
    private static Singleton instance = null;
    private Singleton(){};
    public static Singleton getInstance(){
        if(instance == null){
            instance = new Singleton();
        }
        return instance;
    }
}

2.3 静态常量

public static final 修饰

此变量名全部用大写,多个单词使用下划线连接

public static final COMPANY_NAME="HH"。

引用:类名.COMPANY_NAME;

(接口中的成员变量时静态常量,可用接口名直接访问)

工具类中的方法大多是静态的。

2.4 静态语句块

静态语句块在类初始化时运行一次。

public class A {
    static {
        System.out.println("123");
    } 
    public static void main(String[] args) {
        A a1 = new A();
        A a2 = new A();
    }
}

2.5 静态内部类

只有内部类才能被定义为static。

非静态内部类依赖于外部类的实例,而静态内部类不需要。

静态内部类不能访问外部类的非静态的变量和方法

public class OuterClass {
    class InnerClass {
        public  void print(){
            System.out.println("innerClass");
        }
    }
    static class StaticInnerClass {
        public  void  print(){
            System.out.println("staticInnerClass");
        }
    }
    public static void main(String[] args) {
        //InnerClass innerClass = new InnerClass(); // ERROR:'OuterClass.this' cannot be referenced from a static context
        OuterClass outerClass = new OuterClass();
        InnerClass innerClass = outerClass.new InnerClass();
        innerClass.print();
        StaticInnerClass staticInnerClass = new StaticInnerClass();
        //OuterClass.StaticInnerClass in = new OuterClass.StaticInnerClass();//OK
        staticInnerClass.print();
    }
}

输出:

innerClass
staticInnerClass

2.6 优点:

对对象的共享数据提供单份存储,节省空间

可直接由类名调用,不用在堆内创建对象。

2.7 缺点

访问出现局限性(只可访问静态)。

3. instanceof

用法:boolean b=对象 instanceof  数据类型;

Person p1=new Student();
boolean flag1=p1 instanceof Student;//true
boolean falg2=p1 instanceof Person;//false

instanceof通过返回一个布尔值来指出,这个对象是否是:

  1. 这个特定类或者
  2. 它的子类的一个实例或
  3. 当前接口的实现类

的实例。

注意:如果对象A为null,则返回false。

4. 向上转型

自动

将子类对象赋给一个父类引用(多态)

提高了代码的扩展性

只使用父类共性的内容,无法使用子类特有的功能,要不编译不通过。

5. 向下转型

强制

一个已经向上转型的子类对象可以使用强制类型转换的格式,将父类引用专为子类引用。

在需使用子类特有功能时

易发生ClassCastException异常,所以转换前需要进行类型判断

if(! a  instanceof Dog){...}

Person p=new Student();

Student stu=(Student) p;

如果是直接创建的父类对象,无法向下转型

6. 初始化

原则:

  1. 静态对象(变量)优先于非静态对象(变量)初始化,其中静态对象(变量)只初始化一次,非静态对象(变量)可能初始化很多次;
  2. 父类有限域子类进行初始化;
  3. 按照成员变量的定义顺序进行初始化,即使变量定义散布于方法定义之中,它们依然在任何方法(包括构造函数)被调用之前先初始化

初始化执行顺序:

  • 父类静态变量
  • 父类静态代码块
  • 子类静态变量
  • 子类静态代码块
  • 父类非静态变量
  • 父类非静态代码块
  • 父类构造函数
  • 子类非静态变量
  • 子类非静态代码块
  • 子类构造函数

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值