目录
一、abstract关键字
1.1在class前面使用
在大多数情况下,父类是一个抽象类,无法直接具体化成一个对象,只能找到其子类,此时,在程序中,直接创建父类的对象是没有任何限制的,可以通过在class关键字前面加上abstract关键字,让父类不能直接创建对象,只能被继承。在这种情况下,该父类的作用只是在子类中进行代码复用。
/*定义抽象动物类(父类)*/
public abstract class Animal {
public String breed;
public String sex;
public int age;
public void eat(){
System.out.println("动物正在吃");
}
}
/*定义具体的子类(狗)*/
public class Dog extends Animal{
private String CoatColor;//毛色
@Override
public void eat() {
System.out.println("狗正在啃骨头");
}
public void run(){
System.out.println("狗正在跑");
}
}
/*定义具体子类(猫)*/
public class Cat extends Animal{
@Override
public void eat() {
System.out.println("猫正在吃鱼");
}
public void sleep(){
System.out.println("猫正在睡觉");
}
}
/*主函数*/
public class Test {
public static void main(String[] args) {
//创建狗的对象
Dog dog = new Dog();
//创建猫的对象
Cat cat = new Cat();
//调用相对应的方法
dog.eat();
dog.run();
cat.eat();
cat.sleep();
}
}
1.2在方法前面使用
在上面父类的代码中,eat方法在子类中被重写,那么如论怎样父类中的该方法都不需要被调用,那么可以把它定义为抽象方法,即在该方法前面加上abstract关键字。
如果一个方法前面有abstract关键字,那么该类前面也必须加上abstract关键字,并且需要在子类中重写该方法,如果没有重写该方法,则需要将子类定义为抽象类。
【注】:一个抽象类中可以没有抽象方法,但是抽象方法必然存在于一个抽象类中
二、static关键字
2.1在属性前面使
在类中定义的属性又叫实例(对象)属性,它们有单独的空间,每个之间互不干扰
/*学生类*/
public class Student {
public String name;
public String clasess;
}
}
/*创建两个学生对象*/
public class TestStatic {
public static void main(String[] args) {
Student stu1 = new Student();
stu1.name = "张三";
Stu1.classes = "JAVA01";
Student stu2 = new Student();
stu2.name = "李四";
stu2.classes = "JAVA02";
System.out.println(stu1.name);//输出张三
System.out.println(Stu1.classes);//输出JAVA01
System.out.println(stu2.name);//输出李四
System.out.println(stu2.classes);//输出JAVA02
}
}
在属性前面加上static关键字,无论创建多少个对象都公用同一个存储空间,相互之间操作都会有影响。
/*属性前面有static关键字*/
public class Student {
public String name;
public static String classes;
}
public class TestStatic {
public static void main(String[] args) {
Student stu1 = new Student();
stu1.name = "张三";
Stu1.classes = "JAVA01";
Student stu2 = new Student();
stu2.name = "李四";
Stu2.classes = "JAVA02";
System.out.println(stu1.name);
System.out.println(Stu1.classes);//输出JAVA02
System.out.println(stu2.name);
System.out.println(Stu2.classes);//输出JAVA02
}
}
上面的代码中我们会发现,每次使用classes时会发生警告,根据提示消去警告后会发现可以不需要使用对象访问classes属性,可以直接使用类访问改属性。
public class TestStatic {
public static void main(String[] args) {
Student stu1 = new Student();
stu1.name = "张三";
Student.classes = "JAVA01";
Student stu2 = new Student();
stu2.name = "李四";
Student.classes = "JAVA02";
System.out.println(stu1.name);
System.out.println(Student.classes);
System.out.println(stu2.name);
System.out.println(Student.classes);
}
}
进一步发现,既然可以直接使用类名进行访问该属性,那么不需要创建对象就可以访问该属性。
public class TestStatic {
public static void main(String[] args) {
Student.classes = "JAVA01";
Student.classes = "JAVA02";
System.out.println(Student.classes);
System.out.println(Student.classes);
}
}
2.2在方法前面使用
在方法前面加上static关键字,表示该方法是静态方法,与类有关,与对象无关,即不需要创建对象就可以调用,可以直接使用类名进行调用。
注意:
类方法:
可以调用类属性
可以调用其他类方法
不能调用实例属性
不能调用实例方法
不能调用this、super关键字
实例方法:
可以调用类属性
可以调用类方法
可以调用实例属性
可以调用实例方法
可以调用this、super关键字
static方法只能调用static相关的属性和方法。
2.3代码块
在类中直接用{}包裹的代码,会随着对象的创建而执行。
执行顺序:
分配空间
属性初始化
代码块执行
构造方法执行
public class A {
//代码块
{
System.out.println("代码块被调用");
}
//构造方法
public A(){
System.out.println("A的构造方法被调用");
}
}
2.4静态代码块
使用static关键字修饰的代码块叫做静态代码块。静态代码块在加载类时执行,创建对象时会先加载类。
执行顺序:
静态属性初始化
静态代码块执行
属性初始化
代码块执行
构造方法执行
public class A {
public String name = "aaa";
public static int count = 10;
//代码块
{
System.out.println("代码块被调用===="+this.name);
}
//静态代码块
static {
System.out.println("静态代码块被调用----"+count);
}
//构造方法
public A(){
System.out.println("A的构造方法被调用");
}
}
public class Test {
public static void main(String[] args) {
//创建对象时直接执行代码块中的代码
A a = new A();
}
}
2.5有继承的情况下代码执行顺序
如果B类继承A类,那么在创建B类对象时需要先加载A类,再加载B类,所以最终执行顺序是:
A类加载(静态属性执行,静态代码块执行)
B类加载(静态属性执行,静态代码块执行)
A类创建对象(属性初始化,代码块执行,构造方法执行)
B类创建对象(属性初始化,代码块执行,构造方法执行)
public class A {
String name = "aaa";
static String count = "10";
// 代码块
{
System.out.println("A类中代码块被调用====" + this.name);
}
// 静态代码块
static {
System.out.println("A类中静态代码块被调用-----" + count);
}
public A() {
System.out.println("A的构造方法被调用");
}
}
public class B extends A{
String n = "bbb";
static String c = "20";
// 代码块
{
System.out.println("B类中代码块被调用====" + this.n);
}
// 静态代码块
static {
System.out.println("B类中静态代码块被调用-----" + c);
}
public B() {
System.out.println("B类中的构造方法被调用");
}
}
注意:类加载只会加载一次,加载后常驻内存。所以静态代码块只会在加载时执行一次。通常用来进行一些初始化工作。
三、final关键字
- final修饰类时,该类不能被继承
- final修饰方法时,该方法不能被重写
- final修饰变量时,该变量只能被赋值一次,即该变量实际为常量
注意:
当final修饰基本数据类型时,存储的是实际的值,所以值不能被改变。
当final修饰的引用数据类型(例:数组)时,存储的是地址值,所以地址值不能改变,但是地址值所对应的值可以改变