首页 > 基础资料 博客日记
JavaSE语法阶段复习知识整理3之封装
2024-09-20 08:00:06基础资料围观106次
文章目录
前言:
面向对象程序三大特性:封装、继承、多态。本篇博客主要整理了面向对象之封装的概念,四种访问限定符,包的概念及创建包的操作,包访问权限控制举例,静态成员变量,静态成员方法,静态成员变量的初始化,代码块
一、封装
1.1 封装的概念
封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互
Java中主要通过类和访问权限来实现封装:类可以将数据以及封装数据的方法结合在一起,更符合人类对事物的认知,而访问权限用来控制方法或者字段能否直接在类外使用。
1.2 访问限定符
Java中提供了四种访问限定符:private
、default
、protected
、public
private
:只能在当前类使用
default
:使用这个限定符,什么也不加,代表是包访问权限,只能在当前包中被访问
protected
:可以在同一个包中被访问,或者不同包中的子类中可以被访问(需要注意的是,在修饰变量或方法时并不是在前面写上default,而是什么也不写)
public
:同一个包,不同的包中都可以被访问
代码示例如下:
public class Test {
class Animal {
public String name;//可以被公开访问和使用
String color;//包访问权限,只能在同一个包中被访问
private int age;//只能在当前类中被访问
protected String sex;//在当前包中被访问,或者在当前类的子类中被访问
}
}
1.3封装扩展之包
包的概念
包是对类、接口等的封装机制的体现,是一种对类或者接口等的很好的组织方式,比如:一个包中的类不想被其他包中的类使用。包还有一个重要的作用:在同一个工程中允许存在相同名称的类,只要处在不同的包中即可
导入包中的类
我们常说的导包,其实是导入包中的某个类。比如要使用Scanner
类创建一个对象时,需要用import
导入这个类。这里的 java.util
就是类所在的包, Scanner
就是用到的类。
public class Test {
public static void main(String[] args) {
java.util.Scanner scan = new java.util.Scanner(System.in);
}
}
但是这样写比较麻烦,可以使用import
语句导入包
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
}
}
通配符 *
使用通配符,
import java.util.*
,如果用到了util
底下的某个类,就会加载相对应的类,所以不用担心一次把里面所有类全部加载完
如果要使用java.util
中的多个类甚至所有类,可以使用import java.util.*
,但是不推荐,容易出现冲突的情况,比如以下代码:
import java.util.*;
import java.sql.*;
public class Test {
public static void main(String[] args) {
// util 和 sql 中都存在一个 Date 这样的类, 此时就会出现歧义, 编译出错
Date date = new Date();
System.out.println(date.getTime());
}
}
编译出错
对Date的引用不明确java.sql
中的类java.sql.Date
和java.util
中的类java.util.Date
都匹配
在这种情况下应该使用完整的类名,代码示例如下:
import java.util.*;
import java.sql.*;
public class Test {
public static void main(String[] args) {
java.util.Date date = new java.util.Date();
System.out.println(date.getTime());
}
}
自定义包
基本规则
- 在文件的最上方加上一个 package 语句指定该代码在哪个包中.
- 包名需要尽量指定成唯一的名字, 通常会用公司的域名的颠倒形式(例如 com.baidu.demo1 ).
- 包名要和代码路径相匹配. 例如创建 com.bit.demo1 的包, 那么会存在一个对应的路径 com/baidu/demo1 来存储
代码. - 如果一个类没有 package 语句, 则该类被放到一个默认包中.
操作步骤
-
右键src,选择New,再点击Package
-
输入包的名称,回车(注意包名应全部为小写字母)
-
此时可以看到我们的磁盘上的目录结构已经被 IDEA 自动创建出来了
-
同时我们也看到了, 在新创建的 Test.java 文件的最上方, 就出现了一个 package 语句,说明Test类所在的包
包的访问权限控制举例
如果在www这个包里面创建一个Test1类,类内部定义有 包访问权限的
age
,在不同包 demo包中创建一个Test2类,那么对于age
来说 在不同包中Test2类就不能访问age
,只能在demo这个包中被访问
二、static成员
成员变量分为 静态成员变量 和 实例成员变量
2.1static关键字的引入
static修饰成员变量
以学生类进行举例,代码示例如下
public class Student{
public String name;
public String sex;
public int age;
public Student(String name,String sex,int age) {
this.name = name;
this.sex = sex;
this.age = age;
}
public static void main (String[] args) {
Student stu1 = new Student ("张三","男",18);
Student stu2 = new Student ("李四","男",19);
}
}
以
Student
类创建两个学生对象,那么如果这两个学生都在同一个教室403上课,或者有100个学生对象都在403教室上课,是不是要再加入一个public
修饰的classroom
的成员变量,并且在每次实例化学生对象时,都要输入相同的教室403?如果有非常多的学生,这样会造成大量重复的输入,那么就体现了static
关键字的作用了,我们只需定义一个静态成员变量classRoom
,这个成员变量前用static
进行修饰,说明这个变量是属于类的变量,不依赖于对象,是所有对象共享的,随类的加载而加载,生命周期随类的创建而被加载,随类的卸载而销毁。
代码示例如下
public class Student{
public String name;
public String sex;
public int age;
public static String classRoom = "403";//就地初始化
public Student(String name,String sex,int age) {
this.name = name;
this.sex = sex;
this.age = age;
}
public static void main (String[] args) {
Student stu1 = new Student ("张三","男",18);
Student stu2 = new Student ("李四","男",19);
}
}
2.2静态成员变量初始化
注意:静态成员变量一般不会放在构造方法中来初始化,构造方法中初始化的是与对象相关的实例属性
- 就地初始化:在定义时,直接给出初始值
- 静态代码块初始化:下面会提及…
2.3访问静态成员变量
在其类外使用时需要用类名进行访问,但也可以用当前对象的引用进行访问,但是这种方法不合理。
使用类名访问,代码示例如下
Student.classRoom = 306;
System.out.println(Student.classRoom);
2.4用实际问题加深静态成员变量的理解
- 阅读以下代码,变量
count
的最终值为多少?
class TestStatic {
public static int count = 10;
public static void main(String[] args) {
TestStatic testStatic1 = new TestStatic();
testStatic1.count++;
TestStatic testStatic2 = new TestStatic();
testStatic2.count++;
TestStatic testStatic2 = new TestStatic();
testStatic2.count++;
TestStatic.count--;
System.out.println(count);
}
}
count
的最终值为12,count
被static
修饰,说明count
为静态成员变量,属于类的变量,不管实例化多少个对象,count
也只有独一份,而这一份是随第一次类的加载而创建的,随后对count
的多次操作,都是针对这唯一一个count
操作的。
- 阅读以下代码,变量
age
是否能被打印,打印的数是多少?为什么?
class Person {
public static int age;
}
public class Test{
public static void main(String[] args) {
Person person = null;
System.out.println(person.age);
}
}
能被打印,打印的值为10,;
age
是静态成员变量,不依赖于对象,属于类的变量;Person person = null
说明person
引用不指向任何的对象,而age
本身就独立于对象,所以访问age
和person
引用所指的对象为不为空 没有关系,因为age
是类的变量,不在对象里
2.5静态成员变量的总结要点
- 被
static
修饰的成员变量属于类的变量,储存在方法区中,随类的加载而被加载,不再属于对象,不再依赖于对象。 - 静态成员变量不属于某个对象,是类的属性,是多个对象共享的,即使创建多个对象也不会新增第二个静态成员变量。
- 在其类外使用时需要用类名进行访问,但也可以用当前对象的引用进行访问,但是这种方法不合理。
- 生命周期伴随类的一生:随类的加载而创建,随类的卸载而销毁。(当用类名进行访问类的属性时,类就会被加载,进而这些静态成员变量就会被创建)
- 方法中不能定义和使用静态成员变量,在方法当中定义的变量是局部变量,而静态的变量属于类变量。随着类的加载而被创建,而局部变量是调用该方法的时候,才创建的。所以,此时两种变量的性质是冲突的。Java当中不允许定义局部的静态变量
static修饰成员方法
Java中,被static修饰的成员方法称为静态成员方法,是类的方法,不是某个对象所特有的。静态成员一般是通过
静态方法来访问的。代码示例如下:
public class Student{
// ...
private static String classRoom = "306";
// ...
public static String getClassRoom(){
return classRoom;
}
}
public class TestStudent {
public static void main(String[] args) {
System.out.println(Student.getClassRoom());
}
}
输出:306
2.6静态成员方法的总结要点
- 静态成员方法不属于某个具体的对象,属于类的方法。
- 要用类名的方式调用,也可以用当前对象的引用进行调用,但是这样调用不合理
- 静态成员方法里面不能任何访问非静态的成员变量或成员方法,也不能出现
this
参数,因为这些都是依赖于对象的,而静态成员方法属于类的方法,不依赖于对象
三、代码块
代码块用来初始化成员变量,
实例(构造)代码块:一般用来初始化实例成员变量(非静态成员变量)
静态代码块:一般用来初始化静态成员变量
3.1普通代码块
定义在方法中的代码块,使用
{ }
定义,代码示例如下:
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.2构造代码块
也叫实例代码块,一般用来初始化实例成员变量(非静态成员变量);定义在类的里面,方法的外面,
使用{}
定义,代码示例如下:
public class Student{
public String name;
public int age;
public static String classRoom = "403";//就地初始化
public Student(String name,int age) {
System.out.println("构造方法");
this.name = name;
this.age = age;
}
{
age = 16;
System.out.println("构造代码块");
}
public static void main (String[] args) {
Student stu1 = new Student ("张三",18);
System.out.println(stu1.age);
}
}
运行结果:
构造代码块
构造方法
18
运行结果说明,先执行构造代码块,后执行构造方法
3.3静态代码块
一般用来初始化静态成员变量;定义在类的里面,方法的外面,
使用static {}
定义,代码示例如下:
public class Student{
public String name;
public int age;
public static String classRoom = "403";//就地初始化
public Student(String name,int age) {
System.out.println("构造方法");
this.name = name;
this.age = age;
}
{
age = 16;
System.out.println("构造代码块");
}
static {
classRoom = "309";
System.out.println("静态代码块");
}
public static void main (String[] args) {
Student stu1 = new Student ("张三",18);
System.out.println(Student.classRoom);
}
}
运行结果:
静态代码块
构造代码块
构造方法
309
运行结果说明,执行顺序:静态代码块 > 构造代码块 > 构造方法
另外若有多个静态代码块,执行顺序按照定义代码的先后顺序执行,且静态代码块只会被执行一次
3.4代码块的总结要点
- 静态代码块不管生成多少个对象,其只会执行一次
- 静态成员变量是类的属性,因此是在JVM加载类时开辟空间并初始化的
- 如果一个类中包含多个静态代码块,在编译代码时,编译器会按照定义的先后次序依次执行(合并)
- 实例代码块只有在创建(new)对象时才会执行,只通过类名访问静态成员时,不会被执行
- 执行顺序:静态代码块 > 构造代码块 > 构造方法
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!
标签:
上一篇:【C++】unordered系列
下一篇:线程的六种状态