封装 static 代码块---java

目录

一. 封装

1.1封装的概念

1.2包

1.2.1包的概念

1.2.2导包

1.2.3 自定义包

1.2.4 常见的包

1.3 访问限定符

1.3.1 private限定符

1.3.2default

二. static成员

2.1 static修饰成员变量

2.2 static修饰成员方法

2.3 static成员变量初始化

三. 代码块

3.1 代码块概念以及分类

3.2 普通代码块

3.3 构造代码块/实例代码块

3.4 静态代码块

四. 对象的打印


一. 封装

1.1封装的概念

面向对象程序三大特性:封装、继承、多态 。而类和对象阶段,主要研究的就是封装特性。
何为封装呢?简单来说就是套壳屏蔽细节

1.2包

1.2.1包的概念

在面向对象体系中,提出了一个软件包的概念,即: 为了更好的管理类,把多个类收集在一起成为一组,称为软件 。有点类似于目录。
Java 中也引入了包, 包是对类、接口等的封装机制的体现,是一种对类或者接口等的很好的组织方式 ,比如:一个包中的类不想被其他包中的类使用。包还有一个重要的作用:在同一个工程中允许存在相同名称的类,只要处在 不同的包中即可


1.2.2导包

Java 中已经提供了很多现成的类供我们使用 . 例如: Date 类:可以使用 java.util.Date 导入 java.util 这个包中的 Date .
public class Test {
        public static void main ( String [] args ) {
                java . util . Date date = new java . util . Date ();
                // 得到一个毫秒级别的时间戳
                System . out . println ( date . getTime ());
        }
}
但是这种写法比较麻烦一些 , 可以 使用 import 语句导入包 .
import java . util . Date ; //放在开头
public class Test {
        public static void main ( String [] args ) {
                Date date = new Date ();
                // 得到一个毫秒级别的时间戳
                System . out . println ( date . getTime ());
        }
}

如果想一次性导入java.util中的所有类,可以使用

import java.util.*;  

//* --通配符,要用哪一个类就匹配那个类

//注:不可以这样写import java.util; ,必须要写到后面的类,不知道用什么就用*

可以使用 import static 导入包中静态的方法和字段。
import static java . lang . Math . * ;
public class Test {
        public static void main ( String [] args ) {
                double x = 30 ;
                double y = 40 ;
                // double result = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));(没有写static的情况)
                double result = sqrt ( pow ( x , 2 ) + pow ( y , 2 )); // 静态导入的方式写起来更方便一些,省略了类名
                System . out . println ( result );
        }
}
注意事项 : import C++ #include 差别很大 . C++ 必须 #include 来引入其他文件内容 , 但是 Java 不需要 . import 只是为了写代码的时候更方便 . import 更类似于 C++ namespace using

1.2.3 自定义包

基本规则
1. 在文件的最上方加上一个 package 语句指定该代码在哪个包中 .
2. 包名需要尽量指定成唯一的名字 , 通常会用公司的域名的颠倒形式 ( 例如 com.bit.demo1 ).
3. 包名要和代码路径相匹配 . 例如创建 com.bit.demo1 的包 , 那么会存在一个对应的路径 com/bit/demo1 来存储代码.
4. 如果一个类没有 package 语句 , 则该类被放到一个默认包中
 操作步骤
1. IDEA 中先新建一个包 : 右键 src -> 新建 ->
2. 在弹出的对话框中输入包名 , 例如 com.haha.www
3. 在包中创建类 , 右键包名 -> 新建 -> , 然后输入类名即可 .例如Test
4. 此时可以看到我们的磁盘上的目录结构已经被 IDEA 自动创建出来了
5. 同时我们也看到了 , 在新创建的 Test.java 文件的最上方 , 就出现了一个 package 语句

1.2.4 常见的包

1. java.lang: 系统常用基础类 (String Object), 此包从 JDK1.1 自动导入, 不需要在第一行自己导入,例如:Math, String...
2. java.lang.reflect:java 反射编程包 ;
3. java.net: 进行网络编程开发包。
4. java.sql: 进行数据库开发的支持包。
5. java.util: java 提供的工具程序包。 ( 集合类等 ) 非常重要
6. java.io:I/O 编程开发包。

1.3 访问限定符

Java 中主要通过类和访问权限来实现封装: 类可以将数据以及封装数据的方法结合在一起 ,更符合人类对事物的认知,而访问权限用来控制方法或者字段能否直接在类外使用 Java 中提供了四种访问限定符:

1.3.1 private限定符

private限定符 可以修饰方法, 变量, 构造方法等, 被private修饰,表示该方法, 变量, 构造方法 只能被同一包中的同一类使用, 出了这个包或类就不能被使用,实现了封装.
但是一般我们的构造方法都是使用public修饰的.
Getter and Setter:
一般,我们会用private修饰字段,创建public一个可以获取该字段的方法和一个可以修改该字段的方法, 这样在其他的类中, 如果想要获取或修改该字段, 只需要调用这两种方法.
例如上述代码, 要获取name字段:
修改name字段:
这样,我们就可以间接地对封装的字段进行访问,
如果使用的是IDEA, 可以快速的创建这两种方法:
在相应的位置点鼠标右键 点击Generate
选择想要的功能以及字段即可

1.3.2default

这不是一个关键字,表示的是 什么都不写的情况下. 如果前面什么都不写, 此变量,方法等 只能在同一包里使用,出了此包就不能再使用.
在同一个包中创建两个文件,在Test中定义了一个count,在Test2中可以使用
说明
1. protected 主要是用在继承中,继承部分详细介绍
2. default 权限指:什么都不写时的默认权限
3. 访问权限除了可以限定类中成员的可见性,也可以控制类的可见性
  注意:一般情况下成员变量设置为 private ,成员方法设置为 public
package com . bit . demo1 ;
public class Computer {
        private String cpu ; // cpu
        private String memory ; // 内存
        public String screen ; // 屏幕
        String brand ; // 品牌 ---->default 属性
        //构造方法
        public Computer ( String brand , String cpu , String memory , String screen ) {
                this . brand = brand ;
                this . cpu = cpu ;
                this . memory = memory ;
                this . screen = screen ;
        }
        public void Boot (){
                System . out . println ( " 开机 ~~~" );
        }
        public void PowerOff (){
                System . out . println ( " 关机 ~~~" );
        }
        public void SurfInternet (){
                System . out . println ( " 上网 ~~~" );
        }
}
public class TestComputer {
        public static void main ( String [] args ) {
                Computer p = new Computer ( "HW" , "i7" , "8G" , "13*14" );
                System . out . println ( p . brand ); // default 属性:只能被本包中类访问
                System . out . println ( p . screen ); // public 属性: 可以任何其他类访问
// System.out.println(p.cpu); // private 属性:只能在 Computer 类中访问,不能被其他类访问
        }
}
///
package com . bite . demo2 ;
import com . bite . demo1 . Computer ;
public class TestComputer {
        public static void main ( String [] args ) {
                Computer p = new Computer ( "HW" , "i7" , "8G" , "13*14" );
                System . out . println ( p . screen );
// System.out.println(p.cpu); // 报错: cup 是私有的,不允许被其他类访问
// System.out.println(p.brand); // 报错: brand default ,不允许被其他包中的类访问
        }
}
// 注意:如果去掉 Computer 类之前的 public 修饰符,代码也会编译失败

二. static成员

2.1 static修饰成员变量

static 修饰的成员变量,称为静态成员变量, 属于类变量,  静态成员变量最大的特性: 不属于某个具体的对象,是所有对象所共 享的
【静态成员变量特性】
1. 不属于某个具体的对象,是类的属性,所有对象共享的,不存储在某个对象的空间中
2. 既可以通过对象访问,也可以通过类名访问,但一般更推荐使用类名访问
3. 类变量存储在方法区当中
4. 生命周期伴随类的一生 ( 即:随类的加载而创建,随类的卸载而销毁 )
public class Student {
        public String name ;
        public String gender ;
        public int age ;
        public double score ;
        public static String classRoom = "Bit306" ;
// ...
        public static void main ( String [] args ) {
                // 静态成员变量可以直接通过类名访问
                System . out . println ( Student.classRoom );
                Student s1 = new Student ("Li leilei", "男", 18, 3.8);
                Student s2 = new Student("Han MeiMei", "女", 19, 4.0);
                Student s3 = new Student("Jim", "男", 18, 2.6);
                // 也可以通过对象访问:但是classRoom 是三个对象共享的(不报错,但是会有警告)
                System . out . println ( s1 . classRoom );
                System . out . println ( s2 . classRoom );
                System . out . println ( s3 . classRoom );
        }
}
以调试方式运行上述代码,然后在监视窗口中可以看到,静态成员变量并没有存储到某个具体的对象中。
原因:静态变量不属于任何的对象,是所有对象所共有的.

2.2 static修饰成员方法

一般类中的数据成员都设置为 private ,而成员方法设置为 public ,那设置之后, Student 类中 classRoom 属性如何在类外访问呢?那static 属性应该如何访问呢?
Java 中, static 修饰的成员方法称为静态成员方法,是类的方法,不是某个对象所特有的 。静态成员一般是通过静态方法来访问的。
public class Student {
// ...
private static String classRoom = "Bit306" ;
// ...
public static String getClassRoom (){
return classRoom ;
}
}
public class TestStudent {
public static void main ( String [] args ) {
System . out . println ( Student.getClassRoom() );
}
}
静态方法特性
1. 不属于某个具体的对象,是类方法
2. 可以通过对象调用,也可以通过类名 .静态方法名(...) 方式调用,更推荐使用后者
3. 不能在静态方法中访问任何非静态成员变量,反过来可以
public static String getClassRoom (){
System . out . println ( this.name );
return classRoom ;
}
// 编译失败: Error:(35, 28) java: 无法从静态上下文中引用非静态 变量 this
//原因:
此方法不需要依赖对象的,而this是需要依赖对象的
public static String getClassRoom (){
age += 1 ;
return classRoom ;
}
// 编译失败: Error:(35, 9) java: 无法从静态上下文中引用非静态 变量 age
4. 静态方法中不能调用任何非静态方法,因为非静态方法有 this 参数,在静态方法中调用时候无法传递 this引用,反过来可以
public static String getClassRoom (){
doClass ();
return classRoom ;
}
// 编译报错: Error:(35, 9) java: 无法从静态上下文中引用非静态 方法 doClass()
5. 静态方法无法重写,不能用来实现多态 ( 此处大家暂时不用管,后序多态位置详细讲解 )
所以:
类中的成员变量分为静态成员变量和非静态成员变量
类中的成员方法分为静态成员方法和非静态成员方法

2.3 static成员变量初始化

注意:静态成员变量一般不会放在构造方法中来初始化,构造方法中初始化的是与对象相关的实例属性

静态成员变量的初始化分为两种:就地初始化 和 静态代码块初始化

1. 就地初始化

就地初始化指的是:在定义时直接给出初始值

public class Student {
     
        private static String classRoom = "Bit306" ;
// ...
}

2. 静态代码块初始化 (在后面)

三. 代码块

3.1 代码块概念以及分类

使用 {} 定义的一段代码称为代码块 。根据代码块定义的位置以及关键字,又可分为以下四种:
普通代码块
构造块
静态块
同步代码块(后续讲解多线程部分再谈)

3.2 普通代码块

普通代码块:定义在方法中的代码块,不需要条件,永远会被执行
public class Main {
public static void main ( String [] args ) {
        { // 直接使用 {} 定义,普通方法块
                int x = 10 ;
                System . out . println ( "x1 = " + x );
        }
        int x = 100 ;
        System . out . println ( "x2 = " + x );
}
// 执行结果
x1 = 10
x2 = 100

3.3 构造代码块/实例代码块

构造块:定义在类中的代码块 ( 不加修饰符 ) 。也叫: 实例代码块 构造代码块一般用于初始化非静态成员变量
public class Student {
        //实例成员变量
        private String name ;
        private String gender ;
        private int age ;
        private double score ;
        //实例代码块
        {
                this . name = "bit" ;
                this . age = 12 ;
                this . sex = "man" ;
                System . out . println ( "I am instance init()!" );
        }
        public static void main ( String [] args ) {
                Student stu = new Student ();
        }
// 运行结果
I am instance init () !
注: 实例代码块只有在创建对象时才会执行

3.4 静态代码块

使用 static 定义的代码块称为静态代码块。 一般用于初始化静态成员变量。
public class Student {
        private String name ;
        private String gender ;
        private int age ;
        private double score ;
        private static String classRoom ;
        //实例代码块
        {
                this . name = "bit" ;
                this . age = 12 ;
                this . sex = "man" ;
                System . out . println ( "I am instance init()!" );
        }
        // 静态代码块
        static {
                classRoom = "bit306" ;
                System . out . println ( "I am static init()!" );
        }
        public static void main ( String [] args ) {
                Student s1 = new Student ();
                Student s2 = new Student ();
        }
}
注:当实例代码块和静态代码块同时存在时,先执行静态代码块
注意事项
1. 静态代码块不管生成多少个对象,都会执行, 不依赖于对象, 而且只会执行一次
未创建对象,会运行

2. 静态成员变量是类的属性,因此是在 JVM 加载类时开辟空间并初始化的
3. 当实例代码块和静态代码块同时存在时,先执行静态代码块;
如果同时存在实例代码块和静态代码块和构造方法,先执行静态代码块,再执行实例代码块,最后执行构造方法.
3. 如果一个类中包含多个静态代码块或静态变量,在编译代码时,编译器会按照定义的先后次序依次执行 ( 合并 )

四. 对象的打印

public class Person {
        String name ;
        String gender ;
        int age ;
        public Person ( String name , String gender , int age ) {
                this . name = name ;
                this . gender = gender ;
                this . age = age ;
        }
        public static void main ( String [] args ) {
                Person person = new Person ( "Jim" , " " , 18 );
                System . out . println ( person );
        }
}
// 打印结果: day20210829.Person@1b6d3586
我们发现,通过 System . out . println()打印的时候,实际上调用的是Object的toString的方法
所以想要默认打印对象中的属性, 重写 toString 方法即可。
public class Person {
String name ;
String gender ;
int age ;
public Person ( String name , String gender , int age ) {
this . name = name ;
this . gender = gender ;
this . age = age ;
}
@Override //@...表示注解  @Override表示当前这个方法是被重写的
public String toString () {
return "[" + name + "," + gender + "," + age + "]" ;
}
public static void main ( String [] args ) {
Person person = new Person ( "Jim" , " " , 18 );
System . out . println ( person );
}
}
// 输出结果: [Jim, ,18]
  • 13
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值