final关键字
final表示最终的,在Java中可以用来修饰 类、变量、方法
1.final修饰的类,不能被继承
2.final修饰的变量,不能被重新赋值,修饰后的变量就是常量
3.final修饰的方法,不能被重写
内部类(了解)
把类定义在其他类的内部,这个类就称为内部类
内部类的访问特点:
1.内部类可以直接访问外部类的成员,包括私有的
2.外部类访问内部类的成员,必须要创建对象
package com.iweb.day8.inner1;
public class Outer { //外部类
private int num = 100;
class Inner{ //成员内部类
int num1 = 200; //内部类的属性
public void show(){
System.out.println(num);
System.out.println(num1);
}
}
//外部类的普通方法中,使用内部类的属性,先创建对象
public void hello(){
Inner inner = new Inner();
System.out.println(num);
System.out.println(inner.num1);
}
// public void method(){
// class Inner{ //局部内部类
//
// }
// }
}
package com.iweb.day8.inner1;
import java.util.ArrayList;
import java.util.HashMap;
public class Test {
public static void main(String[] args) {
//创建内部类对象,访问内部类中的show方法
//Inner i = new Inner();
//创建普通的成员内部类对象
//外部类名.内部类名 变量名= 外部类对象.内部类对象
Outer.Inner inner = new Outer().new Inner();
inner.show();
}
}
内部类的分类
成员内部类:在类中的成员位置,定义的类,称为成员内部类。
局部内部类:在局部位置定义的类,称为局部内部类。
成员内部类的修饰符:
private:为了保证数据的安全性
private修饰的内部类,不能被外部调用
static:为了方便访问数据
static修饰的内部类,只能访问外部被static修饰的成员
package com.day11.inner1;
public class Outer { //外部类
private int num = 100;
private static int num2 = 200;
static class Inner{ //成员内部类
int num1 = 200; //内部类的属性
public void show(){
//不能调用外部类非静态成员
// System.out.println(num);
System.out.println(num1);
System.out.println(num2);
hello();
}
public static void show1(){
System.out.println(num2);
hello();
}
}
//外部类的普通方法中,使用内部类的属性,先创建对象
public static void hello(){
Inner inner = new Inner();
System.out.println(inner.num1);
}
}
package com.day11.inner1;
import java.util.ArrayList;
import java.util.HashMap;
public class Test {
public static void main(String[] args) {
//静态内部类中的方法访问
//创建静态内部类对象调用,调用普通方法
Outer.Inner inner = new Outer.Inner();
inner.show();
//可以通过外部类名.内部类名.方法名调用静态方法
Outer.Inner.show1();
}
}
局部内部类的成员访问特点:
1.局部内部类访问外部类的成员,可以正常访问
2.局部内部类访问局部变量,这个局部变量必须是常量,用final修饰 。
为什么局部内部类访问的局部变量必须是常量?
局部变量随着方法加载而调用,随着方法调用完毕而消失,而内部类的对象,是在堆中,堆中的对象将来有垃圾回收器回收,所以,即使对象不用了,也不会马上消失。
加上final 修饰常量,常量的值会一直保存,对象可以继续使用这个值。
jdk1.8中,对于局部内部类访问的局部变量做了优化,,如果被局部内部类访问了,默认认为你是一个final修饰的常量。
package com.day11.inner2;
/*
局部内部类,定义在某个类的方法中的
*/
public class Outer {
private String name = "jack";
private static int num = 100;
public void method(){
System.out.println("这个外部类的method方法");
String s = "hello";
// s = "world";
class Inner{
public void show(){
hello(); //可以直接访问外部类的成员方法
// s = "world";
//可以直接访问外部类的成员属性
System.out.println(name);
System.out.println(num);
//访问局部变量,局部变量必须是常量
System.out.println(s);
System.out.println("这个是局部内部类的方法");
}
}
//方法内部创建内部类对象,并访问内部类的方法
Inner inner = new Inner();
inner.show();
}
public void hello(){
System.out.println("hello~");
}
}
package com.day11.inner2;
public class Test2 {
public static void main(String[] args) {
Outer outer = new Outer();
outer.method();
}
}
匿名内部类
其实是内部类的一个简写的写法
前提:必须要存在一个类或者一个接口,在其它类中继承或者实现,
写法:
class Outer{
new 类或者接口名(){
重写方法
}
}
本质上,匿名内部类,其实是继承了某个类的子类或者是接口的实现类对象。
package com.day11.inner3;
/*
提供给匿名内部类的接口
*/
public interface Inter {
void show1();
void show2();
}
package com.day11.inner3;
public class Outer {
//如果没用匿名内部类去实现接口的步骤是:
//1.创建类,实现接口
//2.实现类重写方法
//3.创建实现类对象,调用方法
//匿名内部类
//把创建接口的实现类、创建对象的步骤都集合在一起了
public void method(){
/* new Inter(){ //new了一个接口的实现类对象
@Override
public void show1() {
System.out.println("匿名内部类重写接口的show1方法");
}
@Override
public void show2() {
System.out.println("匿名内部类重写接口的show2方法");
}
}.show1();
new Inter(){ //new了一个接口的实现类对象
@Override
public void show1() {
System.out.println("匿名内部类重写接口的show1方法");
}
@Override
public void show2() {
System.out.println("匿名内部类重写接口的show2方法");
}
}.show1();
*/
//使用多态的写法改进局部内部类
Inter inter = new Inter() {
@Override
public void show1() {
System.out.println("这是匿名内部类重写接口的show1方法");
}
@Override
public void show2() {
System.out.println("这是匿名内部类重写接口的show2方法");
}
};
inter.show1();
inter.show2();
}
}
package com.day11.inner3;
public class Test {
public static void main(String[] args) {
Outer outer = new Outer();
outer.method();
}
}
练习
package com.day11.inner4;
public interface Inter {
void show();
}
package com.day11.inner4;
public class Outer {
public static Inter method(){
Inter inter = new Inter() {
@Override
public void show() {
System.out.println("HelloWorld");
}
};
return inter;
}
}
package com.day11.inner4;
public class Test {
public static void main(String[] args) {
Outer.method().show();
//Outer类中存在静态方法method()
//show方法来自于接口Inter,将来在method方法中,
//以局部内部类的方式出现
//Outer.method()后面继续调用show方法,
//那么说明method()方法必定返回一个Inter的实现类对象
//执行这个内容,在后台输出一个"HelloWorld"
}
}
类执行顺序
1、
public class Father {
private static String static_field = getStaticField();
private String field = getField();
public int j = 18;
private static String getStaticField() {
System.out.println("父类静态属性");
return "father";
}
private String getField() {
System.out.println("父类属性");
return "father";
}
public Father() {
System.out.println("父类构造方法");
}
static {
System.out.println("父类静态代码块");
}
{
System.out.println("父类代码块");
}
}
public class Son extends Father {
private static String son_static_field = getSonStaticField();
private String son_field = getSonField();
public int i=getI();//属性加载是有顺序的,自上而下加载
public int j = 18;
public final static int z = 18;
private int getI(){
return j;
}
public static String getSonStaticField(){
System.out.println("子类静态属性");
return "son";
}
public String getSonField(){
System.out.println("子类属性");
return "son";
}
public Son() {
System.out.println("子类构造方法");
}
static {
System.out.println("子类静态代码块");
}
{
System.out.println("子类代码块");
}
/**
* 主类所在类初始化,初始化静态方法
* @param args
*/
public static void main(String[] args) {
}
}
public class InitTest {
public static void main(String[] args) {
// Father father = new Father();
// System.out.println("i: " + father.j);
// Son son = new Son();
// System.out.println("i: " + son.i);
// Son.getSonStaticField();
Son[] sons = new Son[12];
}
}
2、
package com.day11.order;
public class Base {
String name = "base";
public Base() {
sayHello();
}
public void sayHello() {
System.out.println(name);
}
}
package com.day11.order;
public class Sub extends Base{
String name="sub";
@Override
public void s
ayHello(){
System.out.println(name);
}
public static void main(String[] args) {
new Sub();//null
}
}