第五章 面向对象(上)
static修饰的成员不能访问没有static修饰的成员
构造器没有返回值,不能使用void声明构造器返回值
如果希望回收该对象,只需对引用赋值null,切断引用与实例的关系
static方法中不能使用this
this:普通方法访问其他方法,成员变量时,无需使用this;如果方法中局部变量与成员变量同名,可使用this访问成员变量。
创建一个对象时,系统内存中有两个东西,堆内存保存对象本身,栈内存保存引用该对象的引用变量
参数可变的形参只能在参数列表最后;一个方法最多包含一个可变参数;可变参数可视为数组;
第六章 面向对象(下)
Java8增强的包装类
字符串类型的值转换为基本类型的值:
包装类提供的parseXxx(String s)静态方法(除了character以外);
包装类提供的valueOf(String s)静态方法;
基本类型变量转换为字符串:
String.valueOf();
把基本类型和""连接;
处理对象
Person p = new Person();
System.out.println(p);
System,out.println(p.toString());
以上两行代码输出一样。都是输出:"类名+@+hashCode"
toString()是为了输出对象的自我描述,可在类中重写该方法。
public String toString(){}
==和equal()方法
==:
对于基本类型变量,如果都是数值类型(不一定要求数据类型严格相同),且变量值相等,则返回true;
对于引用类型,只要在指向同一个对象时,才会返回true;
equal();
可通过重写equal()方法,来提供自定义的相等标准。
重写equal()方法应满足:自反性;对象性;传递性;一致性;对任何不是null的对象,equal(null)返回false
public boolean equals(Object obj){}
final修饰符
final修饰成员变量、局部变量、形参
final修饰成员变量必须由程序员显式指定初始值
final修饰成员变量,在初始化之前不可访问。(其实可以通过方法来访问)
类变量:静态初始化块、声明该变量时初始化
实例变量:非静态初始化块、构造器和声明该变量时初始化
final修饰引用类型变量,只是确保引用类型变量地址不变,即一直指向同一个对象,但是这个对象内容可以改变。
final方法不可以被重写,但可以被重载
final修饰的类不可以有子类
抽象类:
抽象类只有方法签名,没有方法的实现方法
抽象类不能被实例化,只可以被子类继承。
只要类中有一个抽象方法就是抽象类
抽象方法与空方法体的方法不同:抽象方法:public abstract void test();
空方法体方法:public void test(){}
普通类(不包含抽象方法),在添加abstract修饰符后也是抽象方法
static不能与abstract同时修饰方法:static说明说明方法属于类本身,可以被类直接调用;但如果是抽象方法就会在类调用时出现错误
static能与abstract同时修饰内部类
final不能与abstract同时使用:final即不允许被重写,不允许被继承;abstract需要被子类继承,方法被重写
private不能与abstract同时修饰方法:abstract修饰的方法需要被重写,而private禁止访问
接口:
修饰符可以是public或者省略,如果是省略,默认采用包权限访问控制符。
一个接口可以继承多个接口,但不可以继承类。
一个类可以实现多个接口,但只可以继承一个父类,父类继承在接口实现之前。
eg: [修饰符] class ClassName extends 父类 implements 接口1,接口2,接口3...{}
接口中不可以包含:构造器、初始化块
接口中可以包含:成员变量(只能静态变量)、方法(抽象实例方法、类方法、默认方法、私有方法)、内部类(内部接口、枚举)
接口中定义成员变量:会默认加上public static final修饰
接口中定义普通方法:会默认加上public abstract修饰
普通方法不可以有方法实现
但类方法、默认方法、私有方法都必须有方法体
接口中定义内部类、内部接口、内部枚举:会默认加上public static两个修饰符
接口中定义默认方法:必须使用default修饰,会默认加上public修饰。不能使用static修饰。
接口中定义类方法:必须使用static修饰,会默认加上public修饰。
一个类实现接口,必须实现接口中全部方法,否则该类只可以被定义为抽象类。
实现接口方法,必须使用public修饰。因为接口中方法是public修饰,子类只可以更大或者相等。
接口与抽象类:
接口和抽象类都不可以被实例化;
接口和抽象类都可以包含抽象方法;
接口中不可以包含普通方法,但是抽象类可以包含普通方法;
接口中不可以定义普通成员变量,抽象类可以;
接口中不可以包含构造器,抽象类可以;
接口中不可以包含初始化块,抽象类可以;
一个类只有一个父类,但可以实现多个接口
内部类:
内部类可以访问外部类私有成员,但是外部类不可以访问内部类实现细节
内部类可以用public、private、protected、static修饰,但是外部类只可以用public
如果外部类成员变量和内部类成员变量或者内部类中局部变量重名,可以通过this、外部类名.this作为限定区分。
非静态内部类不可以有静态初始化块
在外部类以外的地方使用非静态内部类:
省略访问控制符的内部类,只可以被与外部类在同一个包中的类使用
protected修饰的内部类,可以被与外部类在同一个包中的类和外部类子类使用
public修饰的内部类,可以被任何使用
在外部类以外地上使用内部类: 外部类名.内部类名 name = new 外部类名() . new 内部类名();
eg: Out.In in = new Out().new In();
在外部类以外的地方使用静态内部类:
外部类名.内部类名 name = new 外部类名.内部类名();
eg: Out.In in = new Out.In();
匿名内部类:
只可以继承一个父类或者实现一个接口
匿名内部类不可以是抽象类,不可以有构造器
Lambda表达式:
用于创建函数式接口实例
函数式接口:只有一个抽象方法的接口
(形参列表) -> { 代码块 }
Lambda表达式的常用使用方法:将Lambda表达式赋值给函数式接口类型变量;
将Lambda表达式作为函数式接口类型的参数传送给某个方法
使用函数式接口对Lambda表达式强烈类型转换
枚举类:
enum关键字与class、interface关键字地位相同;
枚举类不能继承父类,但可以实现多个接口
enum定义的非抽象的枚举类会自动添加final关键字
枚举类构造器只可以使用private控制符
枚举类的所有实例必须在枚举类第一行显式列出
枚举类提供了一个values()方法,快速遍历所有枚举值
对象与垃圾回收:
一个对象在堆内存中运行时,根据它被引用变量所引用的状态,可以分为:可达、可恢复、不可达
强制垃圾回收:只是通知系统进行垃圾回收,但系统是否进行回收依然不确定
System.gc();
Runtime.getRuntime.gc();
匿名对象,无引用指向,创建后就进入了可恢复状态
方法重载:方法名同;形参列表不同;java不能使用返回值作为区分方法重载的依据
与成员变量不同,局部变量必须显式初始化。
4个访问控制级别:
private(当前类访问权限):如果一个类里的成员(成员变量、方法和构造器)用private修饰。则只可以在当前类内部被访问。
default(包访问权限):可以被相同包下其他类访问
protected(子类访问权限):可以被同一个包下其他类访问;可以被不同包中子类访问
public(公共访问权限):
import
eg:
import lee.sub...ClassName; //导入指定java类
import lee.sub...*; //导入指定包下全部类
import lee.*; //导入lee包下所有类,但是不包括lee子包中类
import static:导入某个指定类的某个静态成员变量,方法或全部静态成员,方法。
eg:
import static lee.sub...ClassName.fileName|methodName;
//导入ClassName中名为fileName的静态成员和名为methodName的静态方法
import static lee.sub...ClassName.*;
////导入ClassName中所有静态成员和静态方法
构造器重载:可以在构造器中使用this调用另一个构造器的初始化代码。
java只可以继承一个父类,但可以实现多个接口
如果父类方法是private访问权限,则对子类是隐藏的。此时,不是重写。
方法重写:子类包含和父类同名的方法
如果需要在子类方法中调用父类被覆盖的方法,可以使用super关键字。
重载与重写:重载发生在一个类的多个同名方法之间;重写发生在子类与父类同名方法之间。
this、super都不可以出现在static修饰的方法中。
子类调用父类中被覆盖的方法或者变量:
super.method()
super.paraName
在方法中访问名为a的成员变量,但没有显示指定调用者,系统查找a的顺序:
1.查找该方法中是否有a局部变量
2.查找当前类是否包含a成员变量
3.查找当前类的直接父类中是否包含a成员变量,若没有,依次上溯a的全部父类,直到找到a。若没有,返回编译错误。
子类访问被隐藏的父类成员变量:
1.super
2.子类上转到父类
一个构造器调用另一个重载的构造器用this,子类调用父类构造器可以super完成。
重写遵循两同两小一大原则:
方法名相同,参数类型相同
子类返回类型小于等于父类方法返回类型,
子类抛出异常小于等于父类方法抛出异常,
子类访问权限大于等于父类方法访问权限。
多态:
java引用变量有两个类型:编译时类型、运行时类型。编译时类型由声明该变量时使用的类型决定,运行时类型由实际赋给变量的对象决定。
eg: BaseClass B = new SubClass(); BaseClass是编译时类型;SubClass是运行时类型。
引用变量在编译阶段只可以使用编译类型的方法,在运行时才使用运行类型的方法。因此,在编写java时,引用变量只能调用声明该变量时的方法,
Instanceof运算符
判断前一个对象是否是后一个类的实例。
eg:String str = "abc"; str instanceof String = true ;
把子类对象转为父类,上转型。编译时,是父类的方法,执行时是子类的具体方法。
把父类对象转为子类,需要先判断
初始化块:
java类可有4种成员:成员变量、成员方法、构造器、初始化块
初始化块可以没有修饰符,若有,必须为static
当java创建一个对象时,系统先为该对象的所有实例变量分配内存,接着对实例变量执行初始化,初始化顺序:先执行代码块或者声明实例变量时候的初始值,在执行构造器。
静态代码块:在类初始化阶段执行静态代码块。