Java:面向对象(static,代码块,构造方法私有化,内部类)

news2024/12/23 20:02:40

5,static关键字

static是一个特殊的关键字,static的作用是将实例成员变为类成员,只能修饰在类里定义的成员部分(成员变量、方法、内部类(枚举和接口)、初始化块)。static修饰的成员表明它属于这个类本身,而不属于该类的单个实例,因为通常把static修饰的成员变量和方法也称为:类变量、类方法。

5.1,static声明属性

static:使用static声明的属性,此属性为全局属性(静态属性),static声明的属性是所有对象共享的。

class Person{
    static String name;
    private int age;
    public Person(String name,int age) {
        this.setName(name);
        this.age = age;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getMessage(){
        return "姓名:"+name+"   年龄:"+age;
    }
}
public class HelloWord {
    public static void main(String[] args) {
        Person person = new Person("燕双嘤",30);
        Person person2 = new Person("杜马",40);
        System.out.println(person.getMessage()+"  "+person2.getMessage());
        person.setName("步鹰");
        System.out.println(person.getMessage()+"  "+person2.getMessage());
    }
}
==========================================================================
姓名:杜马   年龄:30  姓名:杜马   年龄:40
姓名:步鹰   年龄:30  姓名:步鹰   年龄:40

Java中常用的内存区域:

  • 栈内存空间:保存所有的对象名称(更准确来说是保存了引用的堆内存空间的地址)
  • 堆内存空间:保存每个对象的具体属性内容
  • 全局数据区:保存static类型的属性
  • 全局代码区:保存所有的方法定义

5.2,static声明方法

static声明的方法,被称为“类方法”,可以由类名直接调用。Java中static方法不能被覆盖,因为方法覆盖是基于运行时动态绑定的,而static方法是编译时静态绑定的。static方法跟类的任何实例都不相关,所以概念上不适用。

class Person{
    private static String name;
    private int age;
    public Person(String name,int age) {
        this.setName(name);
        this.age = age;
    }
    public static void setName(String n) {
        name = n;
    }
    public String getMessage(){
        return "姓名:"+name+"   年龄:"+age;
    }
}
public class HelloWord {
    public static void main(String[] args) {
        Person person = new Person("燕双嘤",30);
        Person person2 = new Person("杜马",40);
        System.out.println(person.getMessage()+"  "+person2.getMessage());
        Person.setName("步鹰");
        System.out.println(person.getMessage()+"  "+person2.getMessage());
    }
}
==========================================================================
姓名:杜马   年龄:30  姓名:杜马   年龄:40
姓名:步鹰   年龄:30  姓名:步鹰   年龄:40

Person类将所有的属性都进行了封装,所以要想设置属性就必须使用setter()方法,但是这里的方法是使用static声明的,所以可以直接用类名调用。

另外:非static声明的方法可以去调用static声明的属性或方法。但是static声明的方法是不能调用非static类型声明的属性或方法的。

原因:在程序中所有的属性和方法必须在对象开辟堆内存之后才可以调用,而static类型的方法在对象未被实例化时就可以被类名调用(不在堆栈内存,而在全局数据区内存),所以如果直接由static方法调用非static操作,则有可能在属性还没被初始化时(没放入堆栈内存)就被调用。这也就解释了为啥main方法中调用本类的其他方法只能调用静态方法。

5.3,理解main方法

还记得HelloWord吗?

public class HelloWord {
    public static void main(String[] args) {
        System.out.println("HelloWord");
    }
}
public表示此方法可以被外部调用
static表示此方法可以由类名称直接调用
void主方法是程序的起点,所以不需要任何的返回值
main系统规定好默认调用的方法名称,执行时默认找到main方法名称
String args[]表示的是运行时的参数。参数传递的形式:Java类名称,参数1,参数2,参数3...

6,代码块

6.1,普通代码块

定义变量时指定的初始值和代码块中指定的初始值的执行顺序与它们在源程序的排列顺序相同。

public static void main(String[] args) {
    {
        int x = 30;
        System.out.println(x);
    }
    int x = 40;
    System.out.println(x);
}
===============================
30
40
public static void main(String[] args) {
    int x = 40;
    System.out.println(x);
    {
        x = 30;
        System.out.println(x);
    }
}
===========================
40
30

6.2,构造块

构造代码块是直接写在类中的代码块。构造块优先于构造方法执行,而且每次实例化对象都会执行构造块中的代码,会执行多次。

class Person{
    {
        System.out.println("Hello");
    }
    public Person(){
        System.out.println("Word");
    }
}
public class HelloWord {
    public static void main(String[] args) {
       new Person();
    }
}
============================================
Hello
Word

6.3,静态代码块

class Person {
    {
        System.out.println("父类非静态代码块");
    }

    static {
        System.out.println("父类静态代码块");
    }

    public Person() {
        System.out.println("父类构造方法");
    }
}

public class Child extends Person {
    {
        System.out.println("子类非静态代码块");
    }
    public Child() {
        System.out.println("子类构造方法");
    }
    static {
        System.out.println("子类静态代码块");
    }
    public static void main(String[] args) {
        new Child();
        new Child();
    }
}
===========================
父类静态代码块
子类静态代码块

父类非静态代码块
父类构造方法
子类非静态代码块
子类构造方法

父类非静态代码块
父类构造方法
子类非静态代码块
子类构造方法

静态代码块优先于主方法执行,而在类中定义的静态代码快会优先于构造方法执行,不管有多个个对象产生,静态代码块只执行一次。

7,构造方法私有化

7.1,问题的提出

类的封装性不只体现在对属性的封装上,实际上方法也是可以被封装的。

class Person{
    private Person(){
        System.out.println("构造方法");
    }
}
public class HelloWord {
    public static void main(String[] args) {
        new Person();
    }
}

这样就会报错:'Person()' has private access in 'Package2.Person'

解决办法:在内部产生本类的实例化对象

7.2,问题的解决

class Person{
    static Person instance = new Person();
    private Person(){
        System.out.println("构造方法");
    }
    public void print(){
        System.out.println("你好");
    }
}
public class HelloWord {
    public static void main(String[] args) {
        Person person = Person.instance;
        person.print();
    }
}
============================================
构造方法
你好

程序成功取得了instance的实例化对象并调用了其中的print()方法。但是这样做会存在问题(因为类中的属性必须封装),所以此处应该将instance属性进行封装,而封装之后必须通过方法取得,但以因为instance属性属于静态属性,所以此处必须声明一个静态方法,这样就可以被类名直接调用。

class Person{
    static Person instance = new Person();

    public static Person getInstance() {
        return instance;
    }
    public static void setInstance(Person instance) {
        Person.instance = instance;
    }
    private Person(){
        System.out.println("构造方法");
    }
    public void print(){
        System.out.println("你好");
    }
}
public class HelloWord {
    public static void main(String[] args) {
        Person person1 = Person.getInstance();
        Person person2 = Person.getInstance();
        Person person3 = Person.getInstance();
        person1.print();person2.print();person3.print();
    }
}
=================================
构造方法
你好
构造方法
你好
构造方法
你好

7.3,程序的意义

上面的程序中可以发现虽然声明了3个Person对象,但是实际上所有的对象都只使用一个instance引用,也就是说,此时不管外面如何使用,最终结果程序中也只有一个Person类的实例化对象存在。

这就是是设计模式中的单例设计模式:无论程序怎样运行,Person永远只有一个实例化对象存在,就可以控制实例化对象的产生。

8,内部类

8.1,内部类的基本定义

在内部类可定义成员变量与方法,而且在类内部也可以定义另一个类。Java从JDK1.1开始引入内部类,内部类主要作用如下:

  • 内部类提供了更好的封装,可以把内部类隐藏在外部类之内,不允许同一个包下的其他类访问该类。
  • 内部类成员可以直接访问外部类的私有数据,因为内部类被当成其外部类成员,同一个类的成员之间可以互相访问。
  • 匿名内部类适合于创建那些仅需要一次使用的类。
  • 采用内部类这种技术,可以隐藏细节和内部结构,封装性更好,让程序的结构更加合理!如果类很多且都暴露在外面,那么类与类之间的调用就会十分繁琐!

内部类与外部类的区别:

  • 内部类比外部类可以多使用三个修饰符:private、protected、static——外部类不能使用。
  • 非静态内部类不能拥有静态成员。
class Outer{
    private String info = "hello world!!!";
    class Inner{
        public void print(){
            System.out.println(info);
        }
    };
    public void fun(){
        new Inner().print();
    }
}
public class HelloWord {
    public static void main(String[] args) {
        new Outer().fun();
    }
}
============================================
hello world!!!

Inner类作为Outer类的内部类存在,并且在外部类的fun()方法之中直接实例化内部类的对象并调用方法print(),但是从以上代码中可以明显地发现,内部类的存在实际上已经破坏了一个类的基本结构,因为类是由属性及方法组成的,所以这是内部类的一个缺点。

解决方法如下:

class Outer{
    private String info = "hello world!!!";
    public String getInfo(){
        return this.info;
    }
    public void fun(){
        new Inner(this).print();
    }
}
class Inner{
    private Outer out = null;
    public Inner(Outer out){
        this.out = out;
    }
    public void print(){
        System.out.println(out.getInfo());
    }
}
public class HelloWord {
    public static void main(String[] args) {
        new Outer().fun();
    }
}

8.2,成员内部类(非静态内部类)

成员内部类(非静态内部类)的使用就是将内部类作为外部类的的一个成员变量/成员方法来使用,所以必须依赖于外部类的对象才能调用,用法和成员变量/成员方法一致!

class Outer{
    private static String info = "hello world!!!";
    class Inner{
        public void print(){
            System.out.println(info);
        }
    }
}
public class HelloWord {
    public static void main(String[] args) {
        Outer out = new Outer();
        Outer.Inner in = out.new Inner();
        in.print();
    }
}

8.3,使用static定义内部类(静态内部类)

使用static可以声明属性或方法,而使用static也可以声明内部类,用static声明的内部类变成了外部类,但是用static声明的内部类不能访问非static的外部类属性。如果将info去掉static,则编译时将出现错误。

class Outer{
    private static String info = "hello world!!!";
    static class Inner{
        public void print(){
            System.out.println(info);
        }
    }
}
public class HelloWord {
    public static void main(String[] args) {
        new Outer.Inner().print();
    }
}

8.4,在方法中定义内部类(局部内部类)

可以在方法中定义一个内部类,但是在方法中定义的内部类不能直接访问方法中的参数,如果方法中的参数想要被内部类所访问,必须加上final关键字。

class Outer{
    private String info = "hello world!!!";
    public void fun(final int temp){
        class Inner{
            public void print(){
                System.out.println("类中的属性:"+info);
                System.out.println("方法中的参数:"+temp);
            }
        };
        new Inner().print();
    }
};
public class HelloWord {
    public static void main(String[] args) {
        new Outer().fun(30);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1965463.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

三,搭建环境:事务控制

三&#xff0c;搭建环境&#xff1a;事务控制 文章目录 三&#xff0c;搭建环境&#xff1a;事务控制声明式事务配置注解写法查询操作增删改操作 声明式事务配置 在 demo-module01-web 的模块下的&#xff0c;spring-persist.xml 配置文件中 开启基于注解的声明式事务支持 <…

专硕复试线298/295!哈尔滨理工大学计算机考研考情分析!

哈尔滨理工大学&#xff08;Harbin University of Science and Technology&#xff09;&#xff0c;位于哈尔滨市&#xff0c;是黑龙江省人民政府与国家国防科技工业局共建高校&#xff0c;入选“中西部基础能力建设工程”高校、国家“特色重点学科项目”建设高校、教育部“卓越…

论文速递 | Management Science 5月文章合集

编者按&#xff1a; 在本系列文章中&#xff0c;我们梳理了运筹学顶刊Management Science在2024年5月份发布有关OR/OM以及相关应用的9篇文章的基本信息&#xff0c;旨在帮助读者快速洞察领域新动态。 推荐文章1 题目&#xff1a;Sensitivity Analysis of the Cost Coefficie…

OCC 布尔操作

一、简介 BRepAlgoAPI_Algo 是 OpenCASCADE 中用于布尔操作的基类&#xff0c;提供了布尔运算的基础功能。布尔操作是计算几何中常见的操作&#xff0c;用于对两个形状进行交、并、差运算等。这些操作在 CAD 和 3D 建模中非常重要。 BRepAlgoAPI_Algo 的基本功能 BRepAlgoAPI…

IDEA 插件 Tongyi Lima - 智能生成 Commit Msg 的强大工具

在当今的软件开发过程中&#xff0c;清晰准确的提交信息&#xff08;Commit Msg&#xff09;对于代码的版本控制和团队协作至关重要。而 IDEA 中的 Tongyi Lima 插件为开发者带来了极大的便利&#xff0c;它支持针对 commit 文件进行 AI 生成 commit msg &#xff0c;显著提升了…

DC-2靶机渗透

DC-2靶机渗透回顾 文章目录 DC-2靶机渗透回顾信息收集FLAG1FLAG2FLAG3FLAG4FLAG5 信息收集 nmap进行主机发现和端口扫描&#xff0c;发现开启80,7744端口 进行全扫描查看7744端口其实是ssh服务端口 FLAG1 访问网址&#xff0c;发现加载失败&#xff0c;看url地址看来是需要配…

RHCSA Liunx基础完整版笔记

虚拟机上安装rhel9 网络模式&#xff1a; 桥接模式&#xff1a;与主机使用同一张网卡。要求虚拟机的ip地址与物理机的ip地址在同一个网段 nat模式&#xff1a;该模式会使用vm8网卡与真机网卡进行通讯的。即虚拟机中的网卡与vm8连接&#xff0c;真机网卡与vm8连接。是的真机与…

Monorepo简介

Monorepo 第一章&#xff1a;与Monorepo的邂逅第二章&#xff1a;Multirepo的困境第三章&#xff1a;Monorepo的魔力 - 不可思议的解决问题能力第四章&#xff1a;Monorepo的挑战与应对策略第五章&#xff1a;总结第六章&#xff1a;参考 第一章&#xff1a;与Monorepo的邂逅 …

打开Excel后无法编辑是什么情况?3种解决方法

当发现Excel表格无法编辑&#xff0c;相关菜单选项也都变成灰色状态&#xff0c;无法点击时&#xff0c;可以看看是否以下3个原因造成的&#xff0c;一起来看看对应的解决方法吧。 一、Excel标记为“最终版本” 原因&#xff1a; 当Excel标记为最终版本时&#xff0c;Excel会…

AWS-负载均衡-创建一个对外的HTTPS ALB

目录 介绍 功能差异 适用场景 性能比较 补充 基本组成部分 创建流程 介绍 Elastic Load Balancing 支持三种类型的负载均衡器&#xff1a;Application Load Balancer、Network Load Balancer 和 Classic Load Balancer。这里用ALB( Application Load Balancer)说明。 功…

MySQL之表完整性约束

前言&#xff1a;本博客仅作记录学习使用&#xff0c;部分图片出自网络&#xff0c;如有侵犯您的权益&#xff0c;请联系删除 作用&#xff1a;用于保证数据的完整性和一致性 约束条件说明PRIMARY KEY (PK)该字段为该表的主键&#xff0c;可以唯一的标识记录&#xff0c;不可以…

诚宜开张圣听不应妄自菲薄

拾人牙慧孜孜不倦 青山依旧在几度夕阳红朝闻道夕死可矣 青山依旧在几度夕阳红 安能以血补天我计不成乃天命也臣本布衣躬耕南阳大丈夫宁死不辱尔要试我宝剑是否锋利吗又待怎样休教天下人负我竖子不足与谋皇天不佑天下英雄唯使君与操尔青光殷殷其灿如炎备不量力欲申大义于天下我…

LLM:微调大模型的评估

微调了一个垂直大模型&#xff0c;要判断其好坏&#xff0c;怎么做才算科学的&#xff1f; 一、客观测试集评测 训练的时候&#xff0c;就划分了训练集、验证集、测试集&#xff0c;6:3:1. 验证集用于观察有没有过拟合&#xff0c;一般来说是loss&#xff1b;测试集是在训练完…

【全国大学生电子设计竞赛】2024年E题

&#x1f970;&#x1f970;全国大学生电子设计大赛学习资料专栏已开启&#xff0c;限时免费&#xff0c;速速收藏~

工作流流程引擎框架推荐来了

近期有不少粉丝客户朋友都在询问工作流流程引擎框架推荐。随着行业竞争激烈化&#xff0c;实现流程化办公已经成为当务之急。低代码技术平台及工作流流程引擎拥有够灵活、更可靠、可视化界面等诸多个优势特点&#xff0c;在推动企业实现数字化转型的过程中深受行业信赖与喜爱。…

Go语言生成excel、将excel保存到本地、将多个excel表格压缩为压缩包、在压缩文件上传OSS删除本地excel文件和压缩包

最近在公司了个需求&#xff0c;主要涉及到文件导出&#xff0c;需要根据特定表格文件生成excel文件导出&#xff0c;同时对导出的excel临时保存本地&#xff0c;生成压缩包&#xff0c;将压缩包上传至OSS&#xff08;Object Storage Service&#xff09;后删除本地临时文件。下…

cpu飙升时的排查方式、线上环境常规排查步骤

提示&#xff1a;面试问题&#xff1a;cpu飙升时的排查方式、生产问题排查方式 文章目录 前言一、cpu飙升时的排查步骤1、top2、top -Hp pid3、printf ‘0x%x’ tid4、jstack pid | grep tid 二、总结三、线上环境常规排查步骤1、查看服务器中线程情况2、查看系统异常进程的16进…

JavaEE 从入门到精通(一) ~ Maven

晚上好&#xff0c;愿这深深的夜色给你带来安宁&#xff0c;让温馨的夜晚抚平你一天的疲惫&#xff0c;美好的梦想在这个寂静的夜晚悄悄成长。 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 前言 在软件开发的日常工作中&#xff0c;有效的项目管理是…

OCC 模型编辑

目录 一、简介 二、主要功能 三、常用方法 四、详细子类示例 1、BRepBuilderAPI_Copy 1.1 形状复制 注意事项 1.2 复制和变换 2、BRepBuilderAPI_Transform 3、BRepBuilderAPI_GTransform 3.1 应用广义仿射变换 3.2 平移和旋转变换 3.3 缩放 4、BRepBuilderAPI_Nu…