首页 > 编程语言 >Java中的修饰符——类、方法、变量的修饰

Java中的修饰符——类、方法、变量的修饰

时间:2024-10-13 15:22:46浏览次数:10  
标签:Java 子类 void 修饰符 修饰 抽象类 方法 public

        Java 中的修饰符可以根据其作用对象进行细分,主要包括类的修饰符方法的修饰符变量的修饰符。不同的修饰符适用于不同的场景,以下是对它们的详细划分和解释。

1. 类的修饰符(Class Modifiers)

        修饰符可以用于类声明,影响类的行为和可见性。

  • 访问修饰符

    • public:公共类,任何地方都可以访问。
    • default(不写修饰符):包级私有,只能在同一个包中访问。
  • 非访问修饰符

    • final:表示该类不能被继承(例如 public final class ClassName)。
    • abstract:表示该类是抽象类,不能被实例化,必须由其子类实现(例如 public abstract class ClassName)。
    • strictfp:表示类中的所有浮点数运算都遵循严格的浮点数标准(IEEE 754)。

        接下来具体介绍一下抽象类:

1.抽象类的定义

        抽象类(abstract class是 Java 中用于定义模板或抽象行为的类,它不能直接被实例化,必须通过其子类来实现抽象类中定义的抽象方法。抽象类通常用来描述通用的概念或行为,具体的实现细节由子类提供。

        抽象类使用 abstract 关键字进行声明,通常包含一个或多个抽象方法(没有方法体的方法),但也可以包含普通的(非抽象的)方法。

        基本语法:

abstract class ClassName {
    // 抽象方法
    public abstract void abstractMethod();

    // 普通方法
    public void normalMethod() {
        System.out.println("这是一个普通方法");
    }
}

        

2. 抽象类的特点

  • 不能被实例化:你无法创建抽象类的对象,例如 new ClassName() 是不允许的。抽象类只用于作为其他类的基类。
  • 可以包含抽象方法和具体方法:抽象类既可以定义抽象方法,也可以定义普通方法。子类必须实现抽象方法,但可以继承或重写普通方法。
  • 可以包含成员变量:抽象类可以包含成员变量(属性),并可以在抽象类或其子类中操作这些变量。
  • 可以有构造方法:虽然抽象类不能被实例化,但它可以有构造方法。这个构造方法通常用于子类实例化时,初始化父类中的变量。

3. 抽象方法

        抽象方法是没有方法体的方法,定义了方法的行为但是没有实现,具体的实现由子类提供。声明方式如下:  

public abstract void methodName();

抽象方法的规则:

  • 子类必须实现所有未实现的抽象方法,或者子类本身也必须声明为抽象类。
  • 抽象方法不能有方法体(即不能用 {} 实现逻辑)。

4. 抽象类的使用场景

抽象类通常用于定义一组相关类的共同行为。比如,假设你有一个动物的抽象类,所有动物都有吃和叫的行为,但每种动物吃什么、怎么叫可能不一样。这时候就可以用抽象类来定义通用行为,具体的实现留给子类去完成。

5. 示例:动物抽象类

// 定义一个抽象类 Animal
abstract class Animal {
    // 抽象方法
    public abstract void makeSound();

    // 普通方法
    public void eat() {
        System.out.println("动物在吃东西");
    }
}

// 定义子类 Dog,继承抽象类 Animal
class Dog extends Animal {
    @Override
    public void makeSound() {
        System.out.println("狗叫:汪汪");
    }
}

// 定义子类 Cat,继承抽象类 Animal
class Cat extends Animal {
    @Override
    public void makeSound() {
        System.out.println("猫叫:喵喵");
    }
}

public class Main {
    public static void main(String[] args) {
        // 不能直接实例化抽象类
        // Animal animal = new Animal(); // 错误:抽象类不能实例化

        // 实例化具体的子类
        Animal dog = new Dog();
        Animal cat = new Cat();

        // 调用普通方法和抽象方法
        dog.eat();       // 输出:动物在吃东西
        dog.makeSound(); // 输出:狗叫:汪汪

        cat.eat();       // 输出:动物在吃东西
        cat.makeSound(); // 输出:猫叫:喵喵
    }
}

6. 抽象类与接口的区别

        抽象类与接口有相似之处,但它们的使用场景和设计理念不同:

特性抽象类接口
方法可以包含抽象方法和具体方法只能包含抽象方法(Java 8 后可以包含默认方法和静态方法)
成员变量可以包含成员变量只能包含常量(public static final
构造方法可以有构造方法不能有构造方法
继承关系子类只能继承一个抽象类类可以实现多个接口
适用场景用于定义一类对象的共同行为和属性(具有“是一个”的关系)用于定义一组功能或行为(具有“能做什么”的关系)

7. 抽象类设计原则

  • 抽象类用于共性提取:当一组类有共同的属性或行为时,适合将这些共性提取到抽象类中。子类通过继承获得这些共性行为,同时可以在子类中实现个性化的部分。
  • 避免重复代码:抽象类允许在父类中实现一些通用方法,避免在每个子类中重复编写相同的代码。
  • 适合使用模板设计模式:在一些设计模式中,抽象类可以作为模板方法模式的基础,通过定义骨架方法,让子类实现具体细节。

        抽象类是定义一组具有共性类的强大工具。它允许开发者在父类中提供抽象方法作为子类的契约,也可以提供具体方法来实现通用行为。通过继承,子类可以复用父类的代码,同时提供自己的具体实现。

2. 方法的修饰符(Method Modifiers)

        修饰符用于定义方法的访问权限、行为等。

  • 访问修饰符

    • public:任何地方都可以调用该方法。
    • protected:同一包中的类或继承该类的子类可以调用该方法。
    • default:包级私有,只能在同一个包中调用。
    • private:只有在本类中可以调用。

  • 非访问修饰符

    • static:静态方法,属于类,而不属于某个对象,可以通过类名直接调用(例如 public static void methodName())。
    • final:最终方法,不能被子类重写(例如 public final void methodName())。
    • abstract:抽象方法,没有方法体,必须由子类实现(例如 public abstract void methodName();)。
    • synchronized:同步方法,确保该方法在多线程环境下的线程安全(例如 public synchronized void methodName())。
    • native:本地方法,用其他语言(如 C/C++)实现(例如 public native void methodName())。
    • strictfp:确保方法内的浮点运算遵循 IEEE 754 标准。

3. 变量的修饰符(Variable Modifiers)

修饰符用于定义类成员变量的访问权限、行为等。

  • 访问修饰符

    • public:该变量可以在任何地方访问。
    • protected:该变量可以在同包中的类或继承的子类中访问。
    • default:包级私有,只能在同包中访问。
    • private:该变量只能在本类中访问。
  • 非访问修饰符

    • static:静态变量,属于类,而不属于某个对象,所有实例共享(例如 public static int variableName)。
    • final:最终变量,表示常量,初始化后不能被修改(例如 public final int variableName = 10;)。
    • transient:该变量不会被序列化(例如 transient int variableName)。
    • volatile:该变量在多线程环境下保证可见性和一致性(例如 volatile int variableName)。

4. 总结示例

        举例说明:

public class ExampleClass {
    // 类变量(静态变量)
    public static final String CONSTANT = "常量";

    // 实例变量
    private int instanceVariable;

    // 构造方法
    public ExampleClass(int value) {
        this.instanceVariable = value;
    }

    // 静态方法
    public static void staticMethod() {
        System.out.println("这是一个静态方法");
    }

    // 实例方法
    public void instanceMethod() {
        System.out.println("这是一个实例方法");
    }

    // 同步方法
    public synchronized void synchronizedMethod() {
        System.out.println("这是一个同步方法");
    }
}
  • 类的修饰符控制类的可见性和行为(如 publicabstractfinal)。
  • 方法的修饰符决定方法的可见性和特殊行为(如 publicstaticfinalsynchronized)。
  • 变量的修饰符控制变量的可见性和特性(如 publicstaticfinalvolatile)。

        这种细分有助于开发者更好地管理 Java 程序中的访问控制和功能特性。

5.静态与动态

        在 Java 中,静态(Static)和动态(Dynamic)是两种不同的概念,分别涉及程序在编译时和运行时的行为。它们在 Java 的类、方法、变量的定义和执行时有不同的表现。以下是对这两个概念的详细介绍。

5.1 静态(Static)

        静态通常表示某些元素在编译期或类加载时就被确定,不需要实例化类就可以访问。Java 中的静态与 static 关键字直接相关。

静态的主要特征:

        静态成员变量:用 static 关键字修饰的变量。静态变量属于类而不属于某个实例,所有类的实例共享同一个静态变量。

        示例

class Example {
    static int count = 0; // 静态变量

    public Example() {
        count++;
    }
}

public class Main {
    public static void main(String[] args) {
        Example obj1 = new Example();
        Example obj2 = new Example();
        System.out.println(Example.count); // 输出 2,所有实例共享同一个静态变量
    }
}

        静态方法:用 static 修饰的方法。静态方法属于类,可以通过类名直接调用,而不需要创建类的实例。静态方法不能访问非静态的成员变量或方法,因为它们在类加载时就已经存在,无法依赖于类实例的状态。

        示例

class Example {
    static void staticMethod() {
        System.out.println("这是静态方法");
    }
}

public class Main {
    public static void main(String[] args) {
        Example.staticMethod(); // 通过类名调用静态方法
    }
}

        静态块:用 static 修饰的代码块,用于在类加载时初始化静态变量或执行一些静态初始化操作。静态块只在类第一次加载时执行一次。

        示例

class Example {
    static int value;

    // 静态块
    static {
        value = 100;
        System.out.println("静态块执行");
    }
}

public class Main {
    public static void main(String[] args) {
        System.out.println(Example.value); // 输出 100
    }
}

5.2 动态(Dynamic)

        动态更多与程序的运行时行为相关,通常表示某些元素在运行时才能确定,比如动态绑定、动态分配内存、运行时多态等。Java 中的动态性通常体现在多态(Polymorphism)和动态绑定(Dynamic Binding)。

动态的主要特征:

  • 动态绑定:动态绑定是指在运行时确定方法的调用对象。Java 中的方法调用是基于对象的实际类型在运行时决定的,而不是编译时的引用类型,这就是动态绑定的核心思想。

    • 多态性:多态(Polymorphism)允许同一方法在不同的对象上表现不同的行为。当一个子类重写了父类的方法,并且父类引用指向子类对象时,方法调用根据实际对象类型在运行时动态决定。
    • 示例
class Animal {
    public void sound() {
        System.out.println("动物发出声音");
    }
}

class Dog extends Animal {
    @Override
    public void sound() {
        System.out.println("狗叫:汪汪");
    }
}

class Cat extends Animal {
    @Override
    public void sound() {
        System.out.println("猫叫:喵喵");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal myDog = new Dog();
        Animal myCat = new Cat();

        myDog.sound(); // 输出:狗叫:汪汪(动态绑定到 Dog 的 sound 方法)
        myCat.sound(); // 输出:猫叫:喵喵(动态绑定到 Cat 的 sound 方法)
    }
}
  • 动态方法调用:在编译时,方法的调用可能会根据引用类型来检查方法是否存在,但是具体调用哪个方法是在运行时确定的,依据的是对象的实际类型。动态方法调用与多态紧密相连。

  • 动态加载类:Java 支持在运行时加载类。这通常通过反射机制实现,程序在编译时不需要知道类的完整信息,能够在运行时根据需要动态加载类。例如,Java 提供了 Class.forName("className") 方法来实现动态加载。

    示例
try {
    Class<?> cls = Class.forName("com.example.MyClass");
    Object obj = cls.newInstance();
} catch (Exception e) {
    e.printStackTrace();
}
  • 动态内存分配:Java 通过 new 操作符在运行时为对象分配内存,程序在运行过程中可以动态创建对象。

动态的优点:

  • 灵活性:动态绑定和多态使得代码更加灵活,允许程序在运行时动态决定行为,增强了扩展性。
  • 可扩展性:通过动态加载类和方法,Java 可以在运行时扩展程序的功能,而不需要在编译时定义所有行为。
  • 减少代码耦合:动态绑定和多态使得高层代码与底层实现分离,增强了代码的可维护性。

5.3 静态与动态的比较

特性静态动态
关联时间编译时确定(静态成员、静态方法、静态块等)运行时确定(多态、动态绑定、动态加载类等)
成员访问静态成员属于类,不需要实例化动态行为依赖对象的实际类型,方法调用在运行时动态绑定
使用场景与类相关的操作(如静态变量、静态方法)与运行时行为相关的操作(如多态、动态绑定、反射等)
内存管理静态成员在类加载时就被分配动态对象在运行时分配内存,灵活且适应性强

总结

  • 静态在 Java 中表示与类关联的成员,可以在类加载时确定和使用,具有共享性和高效性。
  • 动态则主要体现在程序的运行时行为,包括动态绑定、多态性、动态加载类等,使得程序具有更强的灵活性和扩展性。

标签:Java,子类,void,修饰符,修饰,抽象类,方法,public
From: https://blog.csdn.net/m0_53926113/article/details/142898692

相关文章

  • 浅谈Java之UDP通信
    一、基本介绍        Java提供了用于处理UDP(用户数据报协议)的类和方法。UDP是一种无连接的网络协议,它允许发送端和接收端之间无需建立连接即可发送数据。在Java中,你可以使用java.net包中的DatagramSocket和DatagramPacket类来实现UDP通信。二、简单用法以下是使用......
  • javase笔记5----泛型
    泛型简介泛型是一种特殊的数据类型。它是Java的一个高级特性。定义一个语法结构时,不用指明具体类型,而是先定义一个类型变量,在真正使用的时候再确定该变量的具体类型。即类型参数化。语法泛型,定义在一对尖括号中,也是一个标识符,一般用在类名后,遵循大驼峰命名法。通常都......
  • JAVA环境配置
    JAVA开发环境配置1.去官网下载JDK找到对应的电脑版本进行安装,记住安装位置2.安装完成后进入我的电脑-属性-高级系统设置-环境变量,点击系统变量下的新建,变量名必须为JAVA_HOME,变量值就是你刚刚的安装路径3.接着在系统变量中找到Path双击,新建如下两个,如图所示如果没有jre可......
  • 基于springboot的社区老人健康管理系统设计与实现java的项目
    前言......
  • 每日OJ题_牛客_NC101压缩字符串(一)_模拟_C++_Java
    目录牛客_NC101压缩字符串(一)_模拟题目解析C++代码Java代码牛客_NC101压缩字符串(一)_模拟压缩字符串(一)_牛客题霸_牛客网(nowcoder.com)描述:        利用字符重复出现的次数,编写一种方法,实现基本的字符串压缩功能。比如,字符串aabcccccaaa会变为a2bc5a3。......
  • java计算机毕业设计在线订餐平台系统(开题+程序+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着互联网技术的飞速发展和人们生活节奏的加快,在线订餐已成为现代都市生活不可或缺的一部分。传统的餐饮消费模式正逐渐被线上化、便捷化的订餐方式......
  • 大学生HTML期末大作业——HTML+CSS+JavaScript游戏网站(英雄联盟)
    HTML+CSS+JS【游戏网站】网页设计期末课程大作业web前端开发技术web课程设计网页规划与设计......
  • 基于Java+Jsp+Html+MySQL实现的企业仓储管理系统设计与实现(源码+文档+部署视频)
    文章目录1.前言2.详细视频演示3.论文参考4.项目运行截图5.技术框架5.1后端采用SpringBoot框架5.2前端框架Vue6.选题推荐毕设案例8.系统测试8.1系统测试的目的8.2系统功能测试9.代码参考10.为什么选择我?11.获取源码1.前言......
  • Java反射专题
    目录一.反射机制1.JavaReflection2.反射相关的主要类3.反射的优缺点4.反射调用优化—关闭访问检查二.Class类1.基本介绍2.常用方法3.获取Class对象的方式4.那些类型有Class对象三.类加载1.介绍2.类加载时机3.类加载各阶段四.获取类结构的信息1.java.lang.Cl......
  • JavaScript中的DOM和Timer(简单易用的基本操作)
    JavaScript中的DOM和Timer基本操作DOM操作传统的选择器选择器idvarelements=document.getElementById(id的名称);例如:varelements=document.getElementById("test");选择id为test的标签选择器classvarelements=document.getElementsByClassName(class的名称);......