目录
| 封装
类与static
类的定义
[public] class 类名{ public 类名(参数列表){ //有参构造方法 } public 类名(){ //无参构造方法 } //Getter 和 Setter 方法 //toString 方法 //hashCode 方法 }
匿名对象
new Scanner(System.in).nextInt();
static关键字
-
被static修饰的【类成员变量、方法】,可以直接通过类名调用(即使通过对象调用,也会被编译为通过类名调用)
-
不能通过 this 和 supper 关键字调用,因为static和实例无关,和类有关
-
因为static方法独立于任何示例,所以不能被abstract修饰
-
静态的方法中不能访问类的非静态变量!只能访问也被static修饰的变量
-
静态方法中可以直接调用本类的其他静态方法
-
类的所有对象共享同一份static数据
-
-
static【静态代码块】,在类初次被加载的时候会被执行一次
-
静态代码块仅在类创建的对象被第一次使用的时候才会调用一次。(而对象构造方法会在对象每次被使用的时候都调用)
-
静态代码块的执行顺序最高,执行顺序:静态高于非静态(内存中,先创建静态,后创建非静态)
-
如果有多个static静态代码块,则会按照其顺序依次执行
-
应用:多个对象使用一个相同的数据 /给对象按照创建地顺序进行编号;
-
权限修饰符
类的不同位置说明
不同修饰符在类的不同位置的访问权限(X代表不能访问):
类的权限修饰符的使用规则(X代表不能使用):
关键字final
final 修饰类
修饰符 final class 类名称(){
//...
}
-
抽象类不能用final修饰
-
当前这个类,不能有任何的子类,进而所有的成员方法不能进行覆盖重写
final 修饰方法
修饰符 final 返回值类型 方法名(参数){
//...
}
-
抽象方法不能用final修饰
-
当前这个方法,不能被覆盖重写
final 修饰局部变量
final 数据类型 局部变量名 = 数值 ;
-
局部变量包括方法的参数、方法内定义的变量
-
局部变量不会进行默认赋值null或者0,因此可以直接赋值,也可以先定义再在之后赋值(如 int num; num=2;)
由于是局部变量,因此无法通过构造方法 / getter 进行赋值
-
只能进行唯一的一次赋值
-
数值不可改变(基本类型值不可改变,引用类型内容可变 但是地址不可改变)
final 修饰成员变量
final 数据类型 成员变量名 = 数值 ;
-
成员变量会进行默认赋值0或者null,所以必须一步完成赋值!(直接 / 构造方法赋值)
不能分步赋值!(无法通过 setter() 进行赋值)
-
只能进行唯一的一次赋值
-
数值不可改变(基本类型值不可改变,引用类型内容可变 但是地址不可改变)
总结
内部类
内部类 VS 类作为成员变量类型
外部类、成员内部类、局部内部类 的修饰符规则
下面介绍一下三大内部类:成员内部类、局部内部类、匿名内部类
成员内部类
-
可以被 public default protected private 修饰
-
内部类可以随意访问所在的类
-
同名变量的处理遵循 this super 规则
-
使用
public class MyClass{
//间接访问内部类。过渡方法
public void innerMethodVisitByOutClass(){
InnerClass inner = new InnerClass();
inner.innerMethod(); //通过这个方法间接调用内部类方法
}
//MyClass的内部类
public class InnerClass{
public void innerMethod(){
//...
}
}
}
class Test{
public void outMethod(){
//使用方法1:直接创建内部类对象
MyClass.InnerClass innerClass = new MyClass().new InnerClass();
//使用方法2:间接调用(通过类中的方法,间接访问内部类)
MyClass myClass = new myClass();
myClass.innerMethodVisitByOutClass();
}
}
局部内部类
-
局部内部类不能被任何权限修饰符修饰!
-
和成员内部类不同的是:局部内部类无法直接创建其对象!因此只能间接调用
-
局部内部类只能使用final修饰的变量
原因:new出来的对象在堆内存中,而局部变量是跟着方法走的 在栈内存当中。方法运行结束之后,立刻出栈,局部变量立刻消失。但是new出来的对象仍然会在堆内存中持续存在,直到垃圾回收消失。此时对象仍然存在,因此如果不把常量换在常量池中(不用final修饰的话),那么此时对象要使用变量的话,就不知道用哪一个了!
-
使用
public class MyClass {
//方法。方法内的都是局部变量
public void localityMethod() {
class LocalityInnerClass{
//.......
}
LocalityInnerClass localityInnerClass = new localityInnerClass(); //在局部内部类所在的方法内,创建局部内部类对象
LocalityInnerClass; //使用局部内部类的属性
}
}
class Test{
public void outMethod(){
MyClass myclass = new MyClass();
myclass.localityMethod(); //间接调用局部内部类
}
}
匿名内部类
-
匿名内部类一般是针对接口而言的。
-
目的:省略了类创建实现类的步骤
-
语法
<span style="background-color:#f8f8f8"><span style="color:#000000">接口名称</span> <span style="color:#000000">对象名</span> <span style="color:#981a1a">=</span> <span style="color:#770088">new</span> <span style="color:#000000">接口名称</span> ( ) { <span style="color:#aa5500">//覆盖重写所有抽象方法 };</span></span>
-
上述语法并不是直接new了接口!本质上还是通过实现类这一中介创建的对象,只不过省略了这一步骤(接口是不能直接new的!)
-
匿名内部类,只能创建唯一一次的对象。若想多次创建对象,要么直接编写一个实现类,要么只能多次进行匿名对象的创建
-
匿名对象 和 匿名内部类 没有任何关系! 前者省略的是对象名字,后者是接口创建对象的时候省略了中间创建实现类的步骤
当然,也可以写一段【匿名对象 + 匿名内部类】的代码,如下
new MyInterfaceObject(){
@Override
public void method(){
System.out.println("方法");
}
}.method();
泛型
-
泛型可以用来代表未知的数据类型
-
泛型不能被继承!即:泛型 E 指定的类型必须一开始就被确定! 如:ArrayList<String> 确定了是String的类型。但是不能写成不确定的ArrayList<Object>
含泛型的类
修饰符 class 类名 <E>{
private E name;
//...
}
含泛型的方法
修饰符 [static] <E> void method(E e){
System.out.println(e);
//...
}
含泛型的接口
修饰符 interface 接口名<E>{
[public abstract] void methodInterface(E e);
}
//使用方法一:在创建实现类的时候 直接指定泛型的数据类型
public class Impl implements 接口名<String>{
@Override
public void methodInterface(String str){
//...
}
}
//使用方法二:接口用什么泛型,实现类就使用什么泛型,创建对象的时候再确定数据类型
public class Impl<E> implements 接口名<E>{
@Override
public void methodInterface(E e){
//...
}
}
Impl<String> impl = new Impl<>();
泛型通配符
-
泛型通配符和 E 很像,区别在于 泛型通配符 ? 只能作为未知的【参数】来使用,而不能当作数据类型来使用!
即:?只能用于方法的参数传递数据,而不能向集合中存储数据
-
总的来说,通配符可以在“遍历任意一个集合元素”的时候使用,作为一个参数在方法中传递
public static void printArray(ArrayList<?> list){
Iterator<?> it = list.iterator();
while(it.hasNext){
Object o = it.next;
//...
}
}
-
受限泛型(了解一下就好)
泛型上限限定 格式 【 ? extends E】 //使用的泛型只能是E类型的 子类/本身
泛型下限限定 格式 【 ? super F】 //使用的泛型只能是F类型的 父类/本身
下一篇介绍Java第二章 | OOP之继承