什么是抽象
- 似是而非的,像却又不是;具备某种对象的特征,但不完整。
不该被创建的对象
public class TestAbstact{
public static void main(String[] args){
Animal a = new Animal();//Animal仅是一种会吃睡的对象,再无其它行为,不够具体、不够完整。
}
}
class Animal{
String breed;
int age;
String sex;
public Animal(){}
public void eat(){
System.out.println("动物在吃...")
}
public void sleep(){
System.out.println("动物在睡...")
}
}
程序是用来模拟现实世界、解决现实问题的;现实世界中存在的都是“动物”具体的子类对象,并不存在“动物”对象,所以,Animal不应该被独立创建成对象。
抽象类
- 应用:abstract修饰类,此类不能new对象。
public class TestAbstact{
public static void main(String[] args){
Animal a = new Animal();//报错!
}
}
abstract class Animal{
String breed;
int age;
String sex;
public Animal(){}
public void eat(){
System.out.println("动物在吃...")
}
public void sleep(){
System.out.println("动物在睡...")
}
}
被abstract修饰的类,称为抽象类。抽象类意为不够完整的类、不够具体的类,抽象类对象无法独立存在,即不能new对象。
抽象类的作用
1.可被子类继承,提供共性属性和方法。
2.可声明为引用,更自然的使用多态。
public class TestAbstact{
public static void main(String[] args){
Animal a1 = new Dog();
Animal a2 = new Cat();
}
}
经验:
抽象父类,可作为子类的组成部分,依附于子类对象存在,由父类共性+子类独有组成完整的子类对象。
不该被实现的方法
abstract class Animal{
public void eat(){
System.out.println("动物在吃...");
}
public void sleep(){
System.out.println("动物在睡...");
}
}
class Dog extends Animal{}
class Cat extends Animal{}
需求:Dog中的eat()应输出“狗在吃骨头”
Cat中的eat()应输出“猫在吃鱼”
父类提供的方法很难满足子类不同需求,如不定义,则表示所有动物都不会吃、睡。如定义,略显多余,多数会被子类覆盖。
抽象方法
abstract class Animal{
public abstract void eat();
}
被abstract修饰的方法,称为抽象方法,只有方法声明,没有方法实现({}的部分)。意为不完整的方法,必须包含在抽象类中。
那么产生继承关系后,子类必须重写父类中所有的抽象方法,否则子类还是抽象类。那么就会报错!
总结
- abstract修饰类:不能new对象,但可以声明引用。
- abstract修饰方法:只有方法声明,没有方法实现。(需包含在抽象类中)
- 抽象类中不一定有抽象方法,但有抽象方法的类一定是抽象类。
- 子类继承抽象类后,必须重写父类中的抽象方法!
实例属性
- 实例属性是每个对象各自持有的独立空间(多态),对象单方面修改,不会影响其他对象。
static
静态修饰符,可以用来修饰属性和方法,一旦被static关键字修饰以后呢,访问的时候呢就要通过
类名.静态属性名 | 类名.静态方法名
❂静态属性是整个类共同持有的共享空间(一份),任何对象修改,都会影响其它对象。
﹡静态成员是全类所有对象共享的成员
﹡在全类中只有一份,不因创建多个对象而产生多份。
静态的特点
- 静态方法允许直接访问静态成员。
- 静态方法不能直接访问非静态成员。
- 静态方法中不允许使用this或是super关键字。
- 静态方法可以继承,不能重写、没有多态。
静态代码块
public class TestStaticBlock{
public static void main(String[] args){
MyClass.method();
}
}
class MyClass{
static String sField = "静态属性";
static {
System.out.println(sField);
System.out.println("静态代码块");
}
public static void method(){
/*无代码
只为触发静态属性的初始化
和静态代码块的执行
*/
}
}
类加载时,触发静态代码块的执行(仅一次)。
执行地位:静态属性初始化之后。
作用:可为静态属性赋值,或必要的初始行为。
注:方法只有被调用才会执行。
类加载
JVM首次使用某个类时,需通过CLASSPATH查找该类的.class文件。
将.class文件中对类的描述信息加载到内存中,进行保存。
- 如类名、包名、父类、属性、方法、构造方法…
加载时机:
- 创建对象。
- 创建子类对象。
- 访问静态属性。
- 调用静态方法
- 主动加载:class.forName(“全限定名”);
final
-
概念:最后的,不可更改的。
-
final修饰的属性名英文字母要大写。
-
final可修饰的内容:
类(最终类)
方法(最终方法)
变量(最终变量)
-
final修饰类:此类不能被继承。
String 、Math、System均为final修饰的类,不能被继承。
-
final修饰方法
此方法不能被重写,不能被覆盖,但可以被继承
final变量
-
final修饰变量:此变量值不能被改变(常量)。
所有final修饰的变量只能赋值一次,值不允许改变。
final实例常量
-
当实例常量被final修饰以后不再提供默认值,必须手动赋予初始值。
赋值时机:显示初始化、构造方法。
注意:如果在构造方法中为实例常量赋值,必须保证所有的构造方法都能对其正确赋值。
public class Car{
final String brand;//实例常量,不再提供默认值,必须赋值,并且只能赋一次
public Car(){
this.name="宝马";
}
public Car(String brand){
this.brand=brand;
}
}
静态常量
public class TestFinal{
public static void main(String[] args){
System.out.println(Student.SCHOOL_NAME);
}
}
class Student{
static final String SCHOOL_NAME;
static{
SCHOOL_NAME = "北京市第一中学";
}
}
-
静态常量不再提供默认值,必须手动赋予初始值。
赋值时机:显示初始化、静态代码块。
注意:在调用时也要以类名.属性名
final修饰的属性名英文字母要大写。
总结
-
final修饰类;此类不能被继承。
-
final修饰方法:此方法不能被覆盖
-
final修饰变量:此变量值不能被改变。(无初始值、只允许赋值一次)
﹡局部常量:显示初始化。
﹡实例常量:显示初始化、构造方法。
﹡静态常量:显示初始化、静态代码块。
﹡基本类型常量:值不可变。
﹡引用类型常量:地址不可变。