01-final关键字
02-abstract抽象类
03-接口
04-内部类
01-final关键字
基本概念: final意思是最后的、最终的,可以修饰类、属性、方法和局部变量。
使用场景:
1.当不希望类被继承时,可以使用final修饰。
2.当不希望父类的某个方法被继承时,可以用final来修饰。
3.当不希望某个属性值被修改时,可以使用final修饰。
4.当不希望局部变量被修改时,可以使用final修饰。
public class Test{ public static void main(String[] args) { System.out.println((new BB).TAX_RATE) // 可以调用) // (new BB).TAX_RATE = 0.99 // 报错,final属性不能修改 } } final class AA { // final 修饰的类不能被其他类继承,但是可以正常的使用这个类。 public int number = 100; // 定义 } class BB { public final double TAX_RATE = 0.88; // final修饰,不可对其更改,但是可以调用 } class CC { public final void eat() { System.out.println("我天天都要干饭"); } } class DD extends CC { // public void eat(){} // 不允许重写该方法 } class EE { public final double TAX_RATE = 0.88; // 1.定义时赋值 public final double TAX_RATE1; { TAX_RATE1 = 0.88 // 2.代码块赋值 } public EE () { // 3.构造器中赋值 TAX_RATE1 = 0.88 } }
注意细节:
1.final修饰的属性又称常量,一般用 XX_XX_XX 命名。
2.final修饰的属性在定义时,必须赋初始值,并且以后不能修改,
可以在如下位置赋值:
1)定义时。
2)前面先声明,在构造器中赋值。
3)前面先声明,在代码块中赋值。
3.如果final修饰的属性是静态属性,则初始化的位置只能是:
1)定义时。
2)在静态代码块中,不能在构造器中(静态属性初始化是在类加载的时候,不会调用构造器)。
4.final类不能继承,但是可以实例化对象。
5.final修饰的方法,不能重写,但是可以继承。
6.final不能修饰构造方法。
7.final和static往往搭配使用,效率更高,底层做了优化,使用时不会导致类加载,提高了效率。
8.包装类(Integer,Double,Float,Boolean)等都是final修饰的类。
02-abstract抽象类
基本概念: 当父类的某些方法不使用,但子类需要继承重写使用时,可以将该方法声明为抽象方法, 难么这个父类就就称为抽象类。
基本使用:
1.用abstract 关键字来修饰一个类时,这个类称为抽象类。
2.用abstract 关键字修饰一个方法时,这个方法称为抽象方法。
3.抽象类的价值更多的在于设计,是设计者设计好,子类继承实现抽象类。
public abstract Animal { // 抽象类 public abstract void call() {}; // 抽象方法,声明了抽象方法,类必须加上abstract }
注意细节:
1.抽象类不能被实例化。
2.抽象类不一定要包含抽象方法。
3.一旦有了抽象方法,则这个类必须声明为abstract。
4.abstract只能修饰类和方法,不能修饰属性。
5.一旦子类继承了抽象类,就必须完成父类的抽象方法。
6.关键字abstract不能和 final、static、private 同时使用。
03-接口
基本概念: 接口就是给定一些没有实现的方法,封装到一起,到某个类要使用的时候,再根据具体情况把这些类写出来。
基本语法:
1.在jdk7以前接口内所有的方法都没有方法体。
2.jdk8以后接口类可以又静态方法,默认方法,接口也可以有自己的方法。
package com.zcc.interface_; import com.zcc.super_.A; public class Interface01 { public static void main(String[] args) { Pig pig = new Pig(); pig.cry(); } } interface Animal { void cry(); } class Pig implements Animal { @Override public void cry() { System.out.println("小猪嗷嗷的叫~~"); } }
注意细节:
1.接口不能被实例化。
2.接口内的所有方法都是public方法,接口中抽象方法,不需要abstract修饰。
3.一个普通类实现接口,必接口内的所有方法。
4.抽象类实现接口,就可以不实现接口内的方法。
实现接口 VS 继承类:
1.继承的主要价值是解决代码的复用性和可维护性,而接口的价值在于设计、设计好各种规范
让其他类来实现。
2.接口比继承更加灵活,继承是 is a 关系,接口是 like a 的关系。
3.接口在一定成都上实现了代码解耦。
接口的多态特性:
// computer 类 package com.zcc.interface_; public class Computer { public void receive(Cominterface cominterface) { // 传入一个 实现了接口的类 可以自动识别类并调用方法 cominterface.show(); } }
04-内部类
基本概念: 一个类的内部完整的嵌套了另一个类结构,被嵌套的类称为内部类,嵌套其他类的类称为外部类,是我们的五大成员之一,内部类最大的特点就是可以直接访问私有属性,并可以体现类与类之间的包含关系。
基本语法:
class Outer { // 外部类 class Inner { // 内部类 } } class Other { // 外部其他类 }
四大内部类:
1.定义在外部类的局部位置上(方法或代码块):
1)局部内部类(有类名)
2)匿名内部类(没有类名)
2.定义在外部类的成员位置上:
1)成员内部类(没有static修饰)
2)静态内部类(使用statci修饰)
一、局部内部类: 局部内部类是定义在外部类的局部位置,有类名。
1.可以直接访问外部类的所有成员,包含私有的。
2.不能添加修饰符,因为他的地位就是一个局部变量,局部变量不能添加修饰符。
3.仅仅在定义它的方法或代码块中。
4.外部类访问局部内部类成员,需要先创建对象,在访问。
5.外部其他类不能访问局部内部类(因为局部内部类是个局部变量)
6.如果内部类和外部类成员重名,调用遵循就近原则,如果想要访问外部类成员,就使用 外部类名.this.成员名 来实现。
package com.zcc.InnerClass; public class Outer { // 外部类 private int i = 100; public void show(){ // 方法 class Inner { // 局部内部类 int i = 10; public void showI(){ // 直接访问i,就近原则 要直接访问外部类 就是使用类名.this.属性名 System.out.println("当前i 的值 =" + i + "外部类的i = " + Outer.this.i); } public Inner getInner(){ return new Inner(); } } Inner inner = new Inner(); inner.showI(); } }
二、匿名内部类: 匿名内部类是定义在外部类的局部位置(方法或代码块),并且没有类名。
基本使用:
1.可以直接房屋内外部类的所有成员,包括私有的。
2.不能添加访问修饰符。
3.作用域仅仅在它的方法或代码块中。
package com.zcc.InnerClass; public class InnerTest { public static void main(String[] args) { Outer outer = new Outer(); outer.show(); // 我今天吃饭了 } } public class Outer { // 外部类 public void show(){ // 方法 // 第一种 AA inner = new AA() { // 类多态的使用,AA 接口类 后面是实现了接口匿名内部类 // 匿名内部类 // 会先创建一个类Outer$1,称为匿名内部类 // 一旦创建了类,就立即创建一个对象,让inner指向它, // 这个类只会被创建一次,后面的人无法调用这个匿名内部类来创建对象。 // 这里的便利类型是接口 AA 而运行类型是 匿名内部类Outer$1 系统分配的类名 public void eat(){ System.out.println("今天我吃饭了") } }; // 这是一个赋值语句,必须添加 ; inner.eat(); // 第二种 // 如果只想调用一个方法,也可以直接调用,这里没有用到类多态的属性,直接调用 new AA() { public void eat() { System.out.println("今天我吃饭了") } }.eat(); } } Interface AA { void eat(); }
三、成员内部类: 成员内部类的成员位置,并且没有static修饰。
1.可以直接访问外部类的成员,包含私有。
2.可以添加任意访问修饰符(public、protected、默认、private),因为它的地位是成员。
3.作用域和外部类的其他成员一样,为整个类体。
4.成员内部类可以直接访问外部类的成员。。
5.外部类可以通过创建对象,在访问成员内部类的成员。
6.外部其他类想要访问成员内部类,外部类必须提供共有的返回内部类的对象,再通过对象访问。
package com.zcc.InnerClass; public class TestInner3 { public static void main(String[] args) { // 第一种 Outer01.inner01 inner01 = new Outer01().new inner01(); inner01.say(); // 第二种 实际上和上一种一致 Outer01 outer01 = new Outer01(); Outer01.inner01 inner011 = outer01.new inner01(); // 第三种 外部类提供返回成员类对象的方法 Outer01.inner01 inner02 = new Outer01().getInstance(); } } class Outer01 { private int i =10; public void show() { System.out.println("show()外部类的成员方法 "); } class inner01 { public int i = 20; public void show() { System.out.println("show()成员内部类的成员方法 "); } public void say(){ System.out.println("say() 成员内部类方法~~~"); // 仍然需要 外部类名.this.属性名 来访问外部类的成员 // System.out.println("直接访问i= " + i + "访问外部的 i = " + Outer01.this.i); // 20 10 show(); //show()成员内部类的成员方法 从本类开始查找 Outer01.this.show(); // show()外部类的成员方法 直接调用外部类show } } public inner01 getInstance() { return new inner01(); } }
四、静态内部类: 静态内部类定义在外部类的成员位置,并且static修饰。
1.可以直接访问外部类的所有静态成员,包括私有的,但不能访问非静态成员。
2.可以添加修饰符(public、protected、默认、prvate),因为它是成员。
3.作用域是同其他成员,为整个类体。
4.静态内部类可以直接访问外部类的成员。
5.外部类可以通过创建对象来访问静态内部类的成员。
6.外部其他类访问静态内部类如下:
package com.zcc.InnerClass; public class TestInner03 { public static void main(String[] args) { // 第一种 Outer02.inner02 inner02 = new Outer02.new Inner02(); inner02.say(); // 第二种 Outer02.inner02 inner02 = (new Outer02()).getInstance(); inner02.say(); } } class Outer02 { private static int n1 =10; private int n2 = 20 ; private static void show(){ System.out.println("外部类的show() 方法"); } static class inner02 { public static int n1 =20 ; public void show(){ System.out.println("外部类的show() 方法"); } public void say() { // 直接访问,就近原则,输出本类的 n1 // 直接访问外部类的方法,因为n1 属于静态属性,所以可以不用对象就可以访问,所以不用this System.out.println("静态内部类的 n1 = " + n1 + " 外部类的 n1 = " + Outer02.n1); show(); // 直接访问 准寻就近原则 Outer02.show(); // 对象名直接访问,直接调用外部类show() // System.out.println("外部类n2的值" + Outer02.n2); 报错,静态方法不能访问外部类非静态成员 } } }Java高级小结,欢迎大家交流学习!!!