2020/8/8
1.static关键字
1.1 static概述
-
概述:表示静态,修饰成员(成员变量和成员方法)。把被当前类所有对象共享的变量定义成静态的。
-
访问方式
对象.静态成员 类.静态成员(推荐) public class Student { //姓名 String name; //年龄 int age; //国籍 static String country; //静态的变量会被所有的对象所共享 //show public void show(){ System.out.println(name + " " + age + " " + country); } public class Test { public static void main(String[] args) { //创建对象 Student s = new Student(); s.name = "柳岩"; s.age = 38; //s.country = "中国"; Student.country = "中国"; Student s2 = new Student(); s2.name = "刘帅雷"; s2.age = 23; //s2.country = "日本"; s.show(); s2.show(); } }
1.2 访问规则
-
静态方法则可以直接访问静态变量和静态方法,只能直接访问静态,不能直接访问非静态。
-
非静态方法可以直接访问静态和非静态。
-
解释了主方法里都加静态
public class AAA { //静态变量 static int a ; //普通变量 int b; //静态方法 public static void method1(){ System.out.println(a); //静态方法可以访问静态变量 System.out.println(b); //静态方法不可以访问非静态变量 method2(); //静态方法可以访问静态方法 method3(); //静态方法不可以访问非静态方法 } public static void method2(){ } //普通方法 public void method3(){ System.out.println(a); System.out.println(b); method1(); method4(); } public void method4(){ } }
1.3 静态内存图
1.4 静态的使用场景
- 如果一个类中,一个变量被多有对象所共享,即可定义成静态的。
- 如果变量想在不创建对象之前使用,即可定义成静态的。
- 如果变量和方法要被静态方法直接调用,就必须定义静态的。
1.5 静态的注意事项
- 静态只能直接调用静态,不能直接调用非静态的。(后产生的不能调用先产生的)
- 只要代码因为静态报错了,就是静态直接调用非静态的。
- 静态方法中不能使用this关键字。
- 静态方法可以被继承,静态方法不能被重写。
2.接口
2.1 接口的概念
-
概念
- 接口就是规范,java中一般某些父类定义成接口,子类需要按照接口规范来编写代码。
-
格式
public interface 接口名{ }
2.2 接口的实现
-
格式
public class 类名 implements 接口名{ }
2.3 接口的成员
接口是比抽象类更抽象的类。
-
接口中的方法
-
抽象方法
意义在于必须让子类重写,给子类提出了一些要求。
//抽象方法 public abstract void method();
默认有public abstract,可以不写
-
静态方法
JDK8
意义在于能够直接调用。
//接口名直接调用 public static void method2(){ System.out.println("静态方法"); }
-
默认方法
JDK8
意义在于能够给子类直接使用。
public default void method(){ System.out.println("默认方法"); }
-
私有方法
JDK9
在本类中重复使用,虽然被继承但不能使用。
意义在于提高本类代码的复用率,把本类中的重复代码写进去。
private void method(){ System.out.println("私有方法"); }
-
-
接口中的变量
- 默认有public static final
- 接口中的成员变量都是常量,使用前必须定义。
2.4 接口的注意事项
-
我们习惯把实现和被实现的关系也叫做子类和父类的关系。
-
接口中的成员变量是常量,默认有三个修饰符 public static final
-
接口的普通方法都是抽象方法,默认有两个修饰符 public abstract
-
接口中不能有构造方法,也不能被创建对象。
抽象类不能创建对象,有构造方法。构造方法的作用是创建对象并给成员变量赋值,接口的成员变量不能修改。
-
接口的实现类必须重写接口的所有抽象方法,或者实现类也是一个抽象类。
2.5 类和接口的关系
-
类与接口的关系
类和类的关系: 单继承:一个类只能继承一个类,亲爹 类和接口的关系: 多实现:一个类可以实现多个接口,干爹 接口和接口的关系: 多继承:一个接口可以继承多个接口,一般不写 开发中常见写法; 一个类在继承一个父类的情况下再实现多个接口 public class DDD extends AAA implements AAA,BBB{ }
-
可能存在的矛盾问腿
- 两个父类中方法名和参数列表相同,返回值类型不同,报错。
- 两个接口中有相同的默认方法,子类必须重写默认方法。
- 多个类本身就有矛盾,不用去记,如果遇到改掉即可。
2.6 综合案例
- 案例图
3.多态
3.1 多态的概念
-
概念
- 一种对象的多种表现形态。一个学生对象是一个学生类型,也是一个人类类型。
-
实例代码
//把一个猫对象赋值给猫类型 Cat c = new Cat(); //把一个猫对象赋值给动物类型 Animal a = new Cat();
-
多态的前提
- 要有继承或者实现关系
- 要有方法的重写
- 要有父类引用指向子类对象
3.2 多态的成员访问规则
-
成员变量
- 编译看左边,运行看左边
-
成员方法
- 编译看左边,运行看右边
-
代码演示
3.3 多态的好处和弊端
- 弊端
- 在多态的情况下,不能调用子类的特有方法。
- 好处
- 多态提高了代码的扩展性。
3.4 多态的转型
-
向上转型
-
把子类类型转成父类类型
Animal a = new Cat(); //多态本身就是向上转型
-
-
向下转型
-
把父类类型转成子类类型
Cat c = (Cat)a; //如果想调用子类的特有成员,就只能向下转型
-
-
类型转换异常
ClassCastException 向下转型可能会出现这种错误
-
instanceof关键字
对象 instanceof 类型 如果对象是后面的这种类型,结果就是true 如果对象不是后面的这种类型,结果就是false
4.内部类
4.1 内部类的概念
- 概念
- 定义在类里面的类就是内部类。
- 分类
- 成员内部类
- 局部内部类
- 匿名内部类
4.2 成员内部类
-
概念:
- 定义在类中方法外的类。
- static可以给内部类加,不能给外部类加。
-
在测试类中创建对象的方式
外部类.内部类 变量名 = new 外部类().new 内部类(); A.B ab = new A().new B();
-
变量重名时的访问
就近原则
-
示例代码
//外部类 public class AAA { //成员变量 int a = 1; //成员内部类 public class BBB{ //成员变量 int a = 10; public void method(){ //局部变量 int a = 20; System.out.println(a); //20就近原则 System.out.println(this.a); //10 System.out.println(AAA.this.a); //1 外部类的成员变量 } } }
4.3 局部内部类
- 概念
- 定义在方法中的内部类。
- 局部内部类的小问题(面试)
- 在局部内部类中调用外部类的局部变量时,这个变量是final类型,不能再修改。
- 在JDK7之前,需要手动加上final
- 在JDK8之后,局部内部类中使用变量就自动有了final。
- 在局部内部类中调用外部类的局部变量时,这个变量是final类型,不能再修改。
//外部类
public class Outer {
//方法
public void method(){
//局部变量
int a = 10;
//局部内部类
class Inner{
public void method(){
System.out.println(a);
//修改时报错
//a = 20;
System.out.println("局部内部类的方法");
}
}
}
}
4.4 匿名内部类
-
概念
- 匿名内部类时局部内部类的一种,匿名内部类就是没有类名的内部类。
-
格式
父类/接口 变量名 = new 父类/接口(){ 方法重写; }
-
代码演示
//方式一: Animal a = new Animal(){ @Override public void eat() { System.out.println("重写方法"); } }; //调用方法 a.eat(); //方式二: new Animal(){ @Override public void eat() { System.out.println("重写方法"); } }.eat();
-
本质
- 就是一个子类对象
-
匿名内部类的作用
- 简化代码,可以少定义一个子类
- 想用就用·,不想用也可以,以后一定会用。
-
所有的类和接口都会生成.class文件