欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Static、继承、抽象类

程序员文章站 2022-03-26 21:07:21
static关键字概述关于 static 关键字的使⽤,它可以⽤来修饰的成员变量和成员⽅法,被修饰的成员是属于类的,⽽不是单单是属于某个对象的。也就是说,既然属于类,就可以不靠创建对象来调⽤了。定义和使⽤格式类变量当 static 修饰成员变量时,该变量称为类变量。该类的每个对象都共享同⼀个类变量的值。任何对象都可以更改该类变量的值,但也可以在不创建该类的对象的情况下对类变量进⾏操作。使⽤static关键字修饰的成员变量static 数据类型 变量名;static int numberID;...

static关键字

概述
关于 static 关键字的使⽤,它可以⽤来修饰的成员变量和成员⽅法,被修饰的成员是属于类的,⽽不是单单是属于某个对象的。也就是说,既然属于类,就可以不靠创建对象来调⽤了。

定义和使⽤格式
类变量
当 static 修饰成员变量时,该变量称为类变量。该类的每个对象都共享同⼀个类变量的值。任何对象都可以更改该类变量的值,但也可以在不创建该类的对象的情况下对类变量进⾏操作。
使⽤static关键字修饰的成员变量

static 数据类型 变量名;
static int numberID; 

静态方法
当 static 修饰成员⽅法时,该⽅法称为类⽅法。静态⽅法在声明中有 static ,建议使⽤类名来调⽤,⽽不需要创建类的对象。调⽤⽅式⾮常简单。

修饰符 static 返回值类型 ⽅法名 (参数列表) {
// 执⾏语句
}
----------------------
public static void showNum() {
System.out.println("num:" + numberOfStudent);
}

静态⽅法调⽤的注意事项:
静态⽅法可以直接访问类变量和静态⽅法。
静态⽅法不能直接访问普通成员变量或成员⽅法。反之,成员⽅法可以直接访问类变量或静态⽅法。
静态⽅法中,不能使⽤this关键字。

静态代码块
概念:定义在成员位置,使⽤static修饰的代码块{ }。
位置:类中⽅法外。
执⾏:随着类的加载⽽执⾏且执⾏⼀次,优先于main⽅法和构造⽅法执⾏。
格式:

public class ClassName {
static {
// 执⾏语句
    }
}

作⽤:给类变量进⾏初始化赋值。⽤法演示,代码如下:

public class Game {
    public static int number;
    static {
// 给类变量赋值
        number = 2;
    }
}

PS:
static 关键字,可以修饰变量、⽅法和代码块。在使⽤的过程中,其主要⽬的还是想在不创建对象的情况下,去调⽤⽅法。下⾯将介绍两个⼯具类,来体现static⽅法的便利。

继承

定义: 就是⼦类继承⽗类的属性和⾏为,使得⼦类对象具有与⽗类相同的属性、相同的⾏为。⼦类可以直接访问⽗类中的⾮私有的属性和⾏为。
好处:

  1. 提⾼代码的复⽤性。
  2. 类与类之间产⽣了关系,是多态的前提。

继承格式

通过 extends 关键字,可以声明⼀个⼦类继承另外⼀个⽗类,定义格式如下:

/*
 * 定义员⼯类Employee,做为⽗类
 */
class Employee {
    String name; // 定义name属性

    // 定义员⼯的⼯作⽅法
    public void work() {
        System.out.println("尽⼼尽⼒地⼯作");
    }
}

/*
 * 定义讲师类Teacher 继承 员⼯类Employee
 */
class Teacher extends Employee {
    // 定义⼀个打印name的⽅法
    public void printName() {
        System.out.println("name=" + name);
    }
}

/*
 * 定义测试类
 */
public class ExtendDemo01 {
    public static void main(String[] args) {
// 创建⼀个讲师类对象
        Teacher t = new Teacher();
// 为该员⼯类的name属性进⾏赋值
        t.name = "⼩明";
// 调⽤该员⼯的printName()⽅法
        t.printName(); // name = ⼩明
// 调⽤Teacher类继承来的work()⽅法
        t.work(); // 尽⼼尽⼒地⼯作
    }
}

继承后的特点——成员变量

成员变量不重名
如果⼦类⽗类中出现不重名的成员变量,这时的访问是没有影响的。

成员变量重名
如果⼦类⽗类中出现重名的成员变量,这时的访问是有影响的。若需要消除影响需要使用到super关键字,修饰父类成员变量,类似于之前学过的this
使用格式:

super.⽗类成员变量名

⼦类⽅法需要修改,代码如下:

class Zi extends Fu {
    // Zi中的成员变量
    int num = 6;

    public void show() {
// 访问⽗类中的num
        System.out.println("Fu num = " + super.num);
// 访问⼦类中的num
        System.out.println("Zi num = " + this.num);
    }
}

演示结果:
Fu num=5

继承后的特点——成员方法

成员方法不重名
如果⼦类⽗类中出现不重名的成员⽅法,这时的调⽤是没有影响的。对象调⽤⽅法时,会先在⼦类中查找有没有对应的⽅法,若⼦类中存在就会执⾏⼦类中的⽅法,若⼦类中不存在就会执⾏⽗类中相应的⽅法。

成员⽅法重名 – 重写(Override)

如果⼦类⽗类中出现重名的成员⽅法,这时的访问是⼀种特殊情况,叫做⽅法重写 (Override)
⽅法重写: ⼦类中出现与⽗类⼀模⼀样的⽅法时(返回值类型,⽅法名和参数列表都相同),会出现覆盖效果,也称为重写或者复写。声明不变,重新实现。

class Fu {
    public void show() {
        System.out.println("Fu show");
    }
}

class Zi extends Fu {
    // ⼦类重写了⽗类的show⽅法
    public void show() {
        System.out.println("Zi show");
    }
}

public class ExtendsDemo05 {
    public static void main(String[] args) {
        Zi z = new Zi();
// ⼦类中有show⽅法,只执⾏重写后的show⽅法
        z.show(); // Zi show
    }
}

重写的应用
⼦类可以根据需要,定义特定于⾃⼰的⾏为。既沿袭了⽗类的功能名称,⼜根据⼦类的需要重新实现⽗类⽅法,从⽽进⾏扩展增强。⽐如新的⼿机增加来电显示头像的功能,代码如下

class Phone {
    public void sendMessage() {
        System.out.println("发短信");
    }

    public void call() {
        System.out.println("打电话");
    }

    public void showNum() {
        System.out.println("来电显示号码");
    }
}

// 智能⼿机类
class NewPhone extends Phone {
    // 重写⽗类的来电显示号码功能,并增加⾃⼰的显示姓名和图⽚功能
    public void showNum() {
// 调⽤⽗类已经存在的功能使⽤super
        super.showNum();
// 增加⾃⼰特有显示姓名和图⽚功能
        System.out.println("显示来电姓名");
        System.out.println("显示头像");
    }
}

public class ExtendsDemo06 {
    public static void main(String[] args) {
// 创建⼦类对象
        NewPhone np = new NewPhone();
// 调⽤⽗类继承⽽来的⽅法
        np.call();
// 调⽤⼦类重写的⽅法
        np.showNum();
    }
}

继承后的特点——构造方法

  1. 构造⽅法的名字是与类名⼀致的。所以⼦类是⽆法继承⽗类构造⽅法的。
  2. 构造⽅法的作⽤是初始化成员变量的。所以⼦类的初始化过程中,必须先执⾏⽗类的初始化动作。⼦类的构造⽅法中默认有⼀个 super() ,表示调⽤⽗类的构造⽅法,⽗类成员变量初始化后,才可以给⼦类使⽤。
class Fu {
    private int n;

    Fu() {
        System.out.println("Fu()");
    }
}

class Zi extends Fu {
    Zi() {
// super(),调⽤⽗类构造⽅法
        super();
        System.out.println("Zi()");
    }
}

public class ExtendsDemo07 {
    public static void main(String args[]) {
        Zi zi = new Zi();
    }
}

输出结果:
Fu()
Zi()

继承小结:
1.子类中的成员变量和父类同名 name
Dog d = new Dog();
d.name -> 就是指自己定义的name,不是继承过来的name
结论: 父子类中的成员变量不要同名
2.子类中可以引用父类对象
super
3.创建子类对象之前, 会先创建父类对象
加载子类之前, 会先加载父类
4.构造方法: 父类的构造方法不能被子类继承的
创建子类对象, 会先默认调用父类的无参构造器
原因: 子类构造方法中, 第一行默认 super()
可以手动调用父类其他构造方法
结论: 子类构造方法中, 一定会先调用父类的构造方法
父类中, 建议先写无参构造器
5.通过子类对象调用方法时
先看子类中有没有定义这个方法, 定义了, 调用子类方法
子类中没有这个方法, 调用父类继承的方法

抽象类

定义: ⽗类中的⽅法,被它的⼦类们重写,⼦类各⾃的实现都不尽相同。那么⽗类的⽅法声明和⽅法主体,只有声明还有意义,⽽⽅法主体则没有存在的意义了。我们把没有⽅法主体的⽅法称为抽象⽅法。Java语法规定,包含抽象⽅法的类就是抽象类。
**抽象⽅法:**没有⽅法体的⽅法。
**抽象类:**包含抽象⽅法的类。

abstract使⽤格式

抽象方法
使⽤ abstract 关键字修饰⽅法,该⽅法就成了抽象⽅法,抽象⽅法只包含⼀个⽅法名,⽽没有⽅法体。

定义格式 :

修饰符 abstract 返回值类型 ⽅法名 (参数列表); 
public abstract void run(); 

抽象类
如果⼀个类包含抽象⽅法,那么该类必须是抽象类。
定义格式:

abstract class 类名字 {

}
public abstract class Animal {
     public abstract void run();
}

抽象使⽤

继承抽象类的⼦类必须重写⽗类所有的抽象⽅法。否则,该⼦类也必须声明为抽象类。最终,必须有⼦类实现该⽗类的抽象⽅法,否则,从最初的⽗类到最终的⼦类都不能创建对象,失去意义。
代码举例 :

public abstract class Animal {
    public abstract void run();
}

public class Cat extends Animal {
    public void run() {
        System.out.println("⼩猫在墙头⾛~~~");
    }
}

public class CatTest {
    public static void main(String[] args) {
// 创建⼦类对象
        Cat c = new Cat();
// 调⽤run⽅法
        c.run();
    }
}
输出结果:
⼩猫在墙头⾛~~~

PS :
抽象方法:
方法没有方法体
一个类中, 存在抽象方法, 那么这个类就必须也是abstract
抽象类:
用abstract修饰的类
抽象类不能直接new对象
有构造方法, 为了给子类使用
抽象类的非抽象子类, 必须实现/重写抽象类的所有抽象方法
判断:
1.有抽象方法的类叫抽象类 √
2.抽象类就是有抽象方法的类 ×
3.抽象类中可以没有抽象方法 √

本文地址:https://blog.csdn.net/qq_45787922/article/details/107344877