abstract
抽象类特点
存在构造方法(自己因不能new不能用,这是给子类用的)
可以有抽象方法,可以有实例方法
抽象方法没有方法体,没 { }加;
总结
abstract修饰类:不能new对象,但可以声明引用。
( abstract 类不能创建对象,但可以声明引用)
abstract修饰方法:只有方法声明,没有方法实现。(需包含在抽象类中)
抽象类中不一定有抽象方法,但有抽象方法的类一定是抽象类。
子类继承抽象类后,必须重写父类中所有的抽象方法,否则子类还是抽象类
抽象类无法实例化对象,但是有构造方法,如果在抽象父类中显示的写了有参构造函数,那么其子类是就显示写出的每个构造函数都必须显示调用父类的构造函数,因为父类中无参构造消失,类实例化时要先实例化父类,父类没有无参构造,只能使用有参构造,所以子类必须调用它的无参。
静态static
静态场景
1当属性,方法不属于对象,属于类,可为静态
2.整个程序只有一份,可为静态,如工具类
工具类(Arrays,Math等)的属性方法都是静态的
静态成员都在方法区(jdk1.7之前叫永久带,之后叫元空间)中,不在栈和堆中。
不通过对象访问,通过类名访问
静态方法可以直接访问静态属性( 格式 类名.),不能直接访问非静态的(因调用静态方式时,实例变量可能还不存在)。实例方法静态非静态都可以访问
静态属性是整个类共同持有的共享空间(一份),任何对象修改,都会影响其他对象。
1.static修饰的成员为静态成员,无需创建对象,可直接通过类名访问。
2.静态方法不能直接访问非静态成员。
3.静态方法中不能使用this或super。
4.静态方法可以继承、不能重写、没有多态。(父类,子类中同名方法是两个不同方法)
5.静态代码块在类加载时被执行,且只执行一次。
用法
修饰属性,方法
静态代码块
静态内部类
静态导入
代码块
1.局部代码块(方法中)
缩小变量使用范围,提前释放局部变量,节省内存
不使用局部代码块
使用局部代码块
2.动态代码块(类中)
实质上是构造方法
加载顺序:初始化实例属性之后,构造方法之前
每次创建对象都要执行一次
动态代码块要书写在实例属性之后,否则报错(非法向前引用)
作用:为实例属性赋值,或必要的初始化话行为
本质上不存在,实际执行时是放在每个构造方法中执行的,下图中的相同部分即为动态代码块
实际:
3.静态代码块
类加载时,触发静态代码块的执行(仅一次)。 (会在main方法执行之前执行)
执行地位:静态属性初始化之后
作用:可为静态属性赋值,或必要的初始行为
类加载
按需加载
将.class文件中对类的描述信息加载到内存中
加载时机:
…创建对象。 • 创建子类对象。 • 访问静态属性。
• 调用静态方法。 • 主动加载:Class.forName(“全限定名”)
静态属性,方法,在类加载时开辟空间,各变量有默认值。对象,在new对象是开辟空间。
对象创建过程:
常量池分为静态常量池 与 运行时常量池
静态常量池:即.class文件中的常量池,是由编辑器产生的,包含各自字面常量和符号引用,还包含类、方法的信息. .class文件主要存储的就是这些。
运行时常量池,即jvm虚拟机在完成类装载操作后,将class文件中的常量池载入到内存中,并保存在方法区中。具有动态性,运行时可以将新的常量放到运行时常量池中.String的intern()方法应用此条属性(JDK 1.7后 字符串常量池在堆中,而其他常量在方法区中)
public class Test {
public static void main(String[] args) {
System.out.println(B.a);
}
}
class A{
public static final int a =10;
static {
System.out.println("A");
}
}
class B extends A{
static {
System.out.println("B");
}
}
仅仅会输出 10,因为使用的是静态常量池中的常量,A,B类均未加载,静态代码块不会执行
若a变为静态变量,会输出 A,10 访问的是A中的a属性,B类未加载
final
修饰的属性方法可以被继承,但不能修改/重写
修饰的类不可被继承,子类中有同名方法会报错
对象常量 修饰对象的,不能更改对象地址,但能修改其属性
final常量只能赋值一次
final实例变量赋值方式
1.声明并赋值
2.构造方法中赋值(动态代码块)
要保证每个构造方法中都要对常量赋值,即无论程序怎样运行,都要保证声明的常量被赋值了,否则报错
final int value;
public MyClass(){
this.value = 0;
}
public MyClass(int value){
this.value = value;
}
final修饰静态变量赋值方式
1声明并赋值 2.静态代码块中赋值
常量:final修饰变量 final int num=5;
分为:
字面常量(5),符号常量(num)
abstract与final或static不能同时使用。final与static可以同时使用
接口interface
• 微观概念:接口是一种能力和约定
• 宏观概念:接口是一种标准
可以声明(可以创建引用),不可以实例化
只有 公开静态常量+公开抽象方法
常量前public static final 可以省略 方法前 public abstract 可以省略
实现接口中的抽象方法时,访问修饰符必须是public
作用:类为单继承,接口为类添加能力
与抽象类的异同
接口多态:与类相同->通过引用
引用的理解
继承关系
类与类 单继承
类与接口 多继承
接口与接口 多继承 extends
常量接口,标记接口
jdk1.8之后接口中可以包含静态方法和默认方法(这里的default不是访问修饰符,是指默认方法,要写出default),其静态方法不能被继承,只能通过接口调用。
面向对象的设计原则
开口里合最单依
开闭原则:开闭原则就是说对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改 原有的代码,而是要扩展原有代码,实现一个热插拔的效果
接口隔离原则:每个接口中不存在子类用不到却必须实现的方法,如果不然,就要将接口拆分。使用 多个隔离的接口,比使用单个接口(多个接口方法集合到一个的接口)要好。
里氏替换原则: 里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。
里氏替换原则中,子类对父类的方法尽量不要重写和重载。因为父类代表了定义好的 结构,通过这个规范的接口与外界交互,子类不应该随便破坏它。
合成/复用原则:原则是尽量首先使用合成/聚合的方式,而不是使用继承。
迪米特法则(最少知道原则):一个类对自己依赖的类知道的越少越好。也就是说无论被依赖的类多么复杂,都应该 将逻辑封装在方法的内部,通过public方法提供给外部。这样当被依赖的类变化时, 才能最小的影响该类。
单一职责原则:不要存在多于一个导致类变更的原因,也就是说每个类应该实现单一的职责,如若不 然,就应该把类拆分。
依赖倒置原则:面向接口编程,依赖于抽象而不依赖于具体。写代码时用到具体类时,不与具体类交 互,而与具体类的上层接口交互。