Static、继承、抽象类
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⽅法的便利。
继承
定义: 就是⼦类继承⽗类的属性和⾏为,使得⼦类对象具有与⽗类相同的属性、相同的⾏为。⼦类可以直接访问⽗类中的⾮私有的属性和⾏为。
好处:
- 提⾼代码的复⽤性。
- 类与类之间产⽣了关系,是多态的前提。
继承格式
通过 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();
}
}
继承后的特点——构造方法
- 构造⽅法的名字是与类名⼀致的。所以⼦类是⽆法继承⽗类构造⽅法的。
- 构造⽅法的作⽤是初始化成员变量的。所以⼦类的初始化过程中,必须先执⾏⽗类的初始化动作。⼦类的构造⽅法中默认有⼀个 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
上一篇: 荐 Spring AOP 的设计与实现
下一篇: 一分钟带你了解:标记-清除算法