类与对象(4)
2023-07-22 18:24:13 107浏览
静态变量
静态变量(类变量),用static关键字修饰的变量就是静态变量,是该类的所有实例化对象共享的变量,任何一个实例化对象去访问它时,取值和修改时,都是同一个变量
class Work{
public static int count = 0;
Work(){ // 无参构造器
count++;
}
}
public static void main(String[] args){
Work w1 = new Work();
System.out.println(w1.count);//1
Work w2 = new Work();
System.out.println(w1.count);//2
}
// 1、static静态变量是同一个类所有对象共享
// 2、static静态变量,在类加载时就已经生成了
1)静态变量与实例变量(普通属性)区别
静态变量是该类的所有对象共享的,而实例变量是每个对象独享的。
2)静态变量可以通过【类名.类变量名】或者【对象名.类变量名】来访问
推荐:使用类名.类变量名方式访问。
【前提是满足访问修饰符的访问权限和范围】
3)静态变量是在类加载时就初始化了,即使没有创建对象,只要类加载了,就可以使用静态变量。
class Work{
public static int count = 0;
Work(){ // 无参构造器
count++;
}
}
public static void main(String[] args){
Work w1 = new Work();
System.out.println(w1.count);//1
Work w2 = new Work();
System.out.println(w2.count);//2
System.out.println(Work.count);
// w1.count === w2.count === Work.count(推荐使用)
// (三者等价)
}
静态方法
静态方法(类方法),用static关键字修饰的方法就是静态方法
1)静态方法中无this的参数,而普通方法中隐含着this的参数
2)静态方法可以通过类名调用,也可以通过对象名调用。
3)静态方法中不允许使用和对象有关的关建字,比如this和super。普通方法(成员方法)可以。
4)静态方法中只能访问静态变量或静态方法。
class Work{
public static int count = 0; // 静态变量
public int m = 1;
public void speak(){
System.out.println(123);
}
// 静态方法
public static void manage(){
System.out.println(count);
//System.out.println(m); 报错
//speak(); 报错
//静态方法中不可以访问非静态成员变量或方法
}
Work(){ // 无参构造器
count++;
}
}
代码块
代码块又称初始化块,属于类中的成员,使用{}将语句封装在方法体中
【无返回值,无方法名,没有返回对象,无参数,只有方法体】
【加载类时自动调用】
修饰符 {
代码部分
};
// 1)修饰符 (不写) 或者 (static)
// 2)没有static修饰的代码块 ---- 普通代码块
// 3)有static修饰的代码块 ---- 静态代码块
// 4);号可写可不写
1)没有static修饰的代码块(普通代码块),每创建对象就会执行一次
2)有static修饰代码块(静态代码块),对类进行初始化,在类加载时自动执行,并且只会执行一次
【static代码块在类加载时执行,只会执行一次】
【普通代码块在创建对象时调用,创建一次,调用一次】
用途:
1)一般用于初始化操作
2)多个构造器中有重复语句,可以抽取到初始化块中,提高重用性
类加载中各部分的优先执行顺序
1)创建对象实例时(会加载类)
2)创建子类对象实例时,父类也会被加载(会加载类信息)
3)使用类的静态成员或静态方法时(会加载类信息)
【相同的类信息只加载一次】
//在创建对象时,类加载的顺序是:
//1、优先调用静态变量和静态代码块 (看先后顺序谁先加载)
//2、调用普通代码块和普通属性(看先后顺序谁先加载)
//3、调用构造方法
class A{
public int a = printa();
public static int aa = printaa();
public A(){
System.out.println("A 的无参构造器被调用");
}
public A(int a){
System.out.println("A 的有参构造器被调用");
}
private static int printaa() {
System.out.println("A 的静态成员变量被加载");
return 0;
}
private int printa() {
System.out.println("A 的普通成员变量被加载");
return 0;
}
{
System.out.println("A 的普通代码块被加载");
}
static{
System.out.println("A 的静态代码块被加载");
}
}
public class Test {
public static void main(String[] args) {
A obj = new A();
System.out.println("=================");
A obj_1 = new A(1);
}
}
//A 的静态成员变量被加载
//A 的静态代码块被加载
//A 的普通成员变量被加载
//A 的普通代码块被加载
//A 的无参构造器被调用
//=================
//A 的普通成员变量被加载
//A 的普通代码块被加载
//A 的有参构造器被调用
final关键字
final可以修饰类、属性、方法和局部变量,被修饰的属性又叫常量,一般均用大写字母命名
特性:
1)final修饰的属性在定义时,必须赋初始值,并且以后不可进行更改
2)final修饰的类,不可以被继承,但是可以实例化对象
3)类没有被final修饰,但是含有final修饰的方法,该方法不可重写,但是该类可以被继承
4)赋值位置(只能赋值一次!)
class Person{
//1、在定义时,直接赋值
public final String ID_CARD = "xxx";
//2、在构造器中
public final String NAME;
Person(){
NAME = "xxx";
}
//3、在代码块中
{
NAME = "xxx";
}
// 如果final修饰的属性是静态的 --- 不可以在构造器中赋值
//1、定义时
public final static int K = 1;
//2、在静态代码块中
static {
K = 1;
}
}
5)通常,final修饰类了,其方法没有必要再使用final进行修饰了
6)final不可以修饰构造器
7)小知识:包装类Integer、Double、Float、String等等都是final修饰的
使用场景:
在某些情况下,程序员可能有以下需求,就会使用final关键字进行修饰
1)当不希望类被继承时
2)当不希望父类的某个方法被子类覆盖/重写(override)时
3)当不希望类的的某个属性的值被修改
4)当不希望某个局部变量被修改
抽象类
在抽象类中给出方法定义,让子类完成重写,在工程项目中起很大作用,其没有确定的方法体
实例:【抽象类给出方法声明,继承抽象类的子类完成具体方法体】
abstract class Animal{
void eat();
void drink();
void run();
}
class Dog extends Animal{
@Override
public void eat() {
System.out.println("狗 eat");
}
@Override
public void drink() {
System.out.println("狗 drink");
}
@Override
public void run() {
System.out.println("狗 run");
}
}
class Cat extends Animal{
@Override
public void eat() {
System.out.println("猫 eat");
}
@Override
public void drink() {
System.out.println("猫 drink");
}
@Override
public void run() {
System.out.println("猫 run");
}
}
特点:
1)抽象类不能被实例化
2)抽象类可以没有abstract修饰的方法
3)一旦包含了abstract修饰的方法,这个类必须声明为abstract
4)abstract只能修饰类和方法,修饰方法时没有方法体
5)一个类继承了抽象类,必须实现抽象类的所有抽象方法,除非这个类也声明为abstract类
6)抽象方法不可使用private、static、final来修饰
【抽象方法的本质就是在子类中被重写,这些关键字与其相违背】
接口
接口就是给出一些没有实现的方法,封装到一起,到某个类使用的时候,在根据具体情况把这些方法进行实现
特点:
1)接口可以有自己的属性和方法
2)接口不可以被实例化
3)接口中所有的方法是public方法,抽象方法可以不用abstract修饰
4)一个普通类实现接口,就必须将该接口的所有方法都实现
5)抽象类实现接口,可以不用实现借口的方法
6)一个类可以实现多个接口,接口名用,号隔开
7)接口中的属性,默认为public static final 修饰
int a = 10; ---- public static final int a =10;
8)一个接口不能继承其他的类,但是可以继承多个别的接口
9)接口的修饰符只能public 和默认,这点与类的修饰符相同
实例:
// 主函数
public class Test {
public static void main(String[] args) {
Live L = new Live();
Dog d = new Dog();
Cat c = new Cat();
L.living(d);
L.living(c);
}
}
// 接口 interface关键字 进行修饰
interface Animal{
String NAME = "动物";
// 默认等价于 public static final String NAME = "动物"
public abstract void eat();
public abstract void drink();
public abstract void run();
}
// 接口实现类
class Dog implements Animal{
@Override
public void eat() {
System.out.println("狗 eat");
}
@Override
public void drink() {
System.out.println("狗 drink");
}
@Override
public void run() {
System.out.println("狗 run");
}
}
// 接口实现类
class Cat implements Animal{
@Override
public void eat() {
System.out.println("猫 eat");
}
@Override
public void drink() {
System.out.println("猫 drink");
}
@Override
public void run() {
System.out.println("猫 run");
}
}
class Live{
public void living(Animal animal){
animal.eat();
animal.drink();
animal.run();
}
}
好博客就要一起分享哦!分享海报
此处可发布评论
评论(0)展开评论
展开评论