JAVA学习-06-韩顺平老师
JAVA高级-02
目录:
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以后接口类可以又静态方法,默认方法,接口也可以有自己的方法。
/*
interface 接口名 {
属性
方法
}
class 类名 implements 接口 {
自己的属性
自己的方法
必须实现的接口的抽象的方法
}
*/
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.作用域仅仅在它的方法或代码块中。
/*
new 类或接口(参数列表) {
类体
}
*/
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();
/*如果 getInstance 方法 是 静态方法
可以直接 通过Outer02类名调用
Outer02.inner02 inner02 = 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高级小结,欢迎大家交流学习!!!