首页 > Python资料 博客日记
Java类和对象(二)—— 封装,static 关键字与代码块
2024-06-03 03:00:05Python资料围观136次
前言
在面向对象的编程语言中,有三大特性:封装、继承和多态~~
今天我们就来学习封装的知识
封装
什么是封装
在现实生活中,我们经常使用手机来进行沟通与交流,实际上我们拿到的手机是被封装好的,精美的屏幕,还有一些接口等等,但是手机内部的结构我们是看不到的,除非你强行拆解~~
手机的内部结构:
手机厂商会把手机的内部结构(手机的细节)给封装起来,就是套上一个壳子,留下几个接口实现用户与手机之间的交互,这就是封装的意思~~
封装的延伸之包
在生活中,我们会使用文件夹来存放不同类型的文件,每一个大的文件夹下可能会用不同的小文件,这些大文件夹我们可以理解成包,小文件夹可以理解成包里面的某一个类,在小文件夹里面有一些文件,这些文件可以理解成方法~~
包是对类、接口等的封装机制的体现,是一种对类或者接口等的很好的组织方式
在Java中我们可以使用Java已经有的包,或者自己自定义一些包~
常见的Java的包有:
1.java.lang:系统常用基础类(String、Object),此包从JDK1.1后自动导入。
2.java.lang.reflect:java 反射编程包;
3.java.net:进行网络编程开发包。
4.java.sql:进行数据库开发的支持包。
5.java.util:是java提供的工具程序包。(集合类等) 非常重要
6.java.io:I/O编程开发包。
举个例子,我们在打印数组的时候可以使用Arrays.toString()来实现数组转化成字符串~
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
int[] arr = {1,2,3};
System.out.println(Arrays.toString(arr));
}
}
要使用Arrays.toString()这个方法的时候,我们会导入一个java.util的包,并且说明导入这个包底下的哪一个类~
导入包中的类
我们一般会使用下面的形式来导入包中的类:
方式一
直接使用包的名字来使用包里面的类里面的方法:
包名.类名.方法
public class Test {
public static void main(String[] args) {
int[] arr = {1,2,3};
System.out.println(java.util.Arrays.toString(arr));
}
}
因为每次使用都要写一遍这些语句(包名.类名.方法),所以这种一般这种比较麻烦,我们不推荐使用~~
方式二
使用import 语句来导入包里面的类:
import 包名.类名;
就例如下面的方式:
import java.util.Arrays;
这种显式导入包里面的类是十分推荐的~
还有一种就是直接把包里面所有的类直接导入进来:
import java.util.*;
import java.sql. *;
但是这种我们不推荐,因为别人就不知道你使用了这个包的哪个类,代码的可读性就会变差,而且如果不同的包有一些类名是一样的,编译器就不知道要使用哪一个类了:
我们可以使用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));
double result = sqrt(pow(x, 2) + pow(y, 2));
System.out.println(result);
}
}
方式三
IDEA可以使用快捷键进行导入,鼠标移动到这个需要导入的类,按住Alt+回车就可以了~~
自定义一个包
创建一个包
这里使用的是IDEA编译器进行演示:
首先右键src,选择new,点击package,然后输入你的包名,就可以了~~
没错,包里面其实可以再套包,如果你输入的包名类似com.baidu.www(就会创建三个包,com里面有baidu,baidu里面有www)
如果你建立了类似上面的很多包,但是你看不到层次分明的包的话,可以这样修改:
把Compact Middle Packages 这个勾(√)给取消掉就可以了~~
编译器会在第一行就告诉你这个类是在哪一个包下的~~
会显示package+包名;
规则
在文件的最上方加上一个 package 语句指定该代码在哪个包中.
包名需要尽量指定成唯一的名字, 通常会用公司的域名的颠倒形式(例如 com.baidu.www ).
包名要和代码路径相匹配. 例如创建 com.baidu.www 的包, 那么会存在一个对应的路径 com/baidu/www 来存储
代码.
如果一个类没有 package 语句, 则该类被放到一个默认包中.
使用
要使用自己的包也很简单,还是一样要导入包里面的类
import com.baidu.www.Test2;
public class Test {
public static void main(String[] args) {
Test2 test = new Test2();
}
}
static
我们在使用创建对象的时候,有时候会发现有些成员变量是不变的,例如:同样在一个班里的学生,他们的姓名、年龄是不一样的,但是不变的是他们的班级,他们有些行为也是一样的(例如上课、睡觉、吃饭等等)
这时候我们就会使用static来修饰这些共性的特征
在Java中,被static修饰的成员,称之为静态成员,也可以称为类成员,其不属于某个具体的对象,是所有对象所共享的。
static 修饰成员变量
上面我们提到学生类,接下来我们就以这个来举例子:
public class Student {
public String name;
public int age;
public String className;
public static void main(String[] args) {
Student student1 = new Student();
Student student2 = new Student();
Student student3 = new Student();
}
}
我们使用 static 来修饰班级名字,意味着className 这个成员变量是共享的,并且是存放在方法区当中的,而且只会存储一份~~
static修饰的成员变量,称为静态成员变量,也可以叫做类变量,静态成员变量最大的特性:不属于某个具体的对象,是所有对象所共享的。
由于静态成员变量是不依赖对象的,所以我们可以使用类名直接访问静态成员变量,当然也可以使用对象来访问~~
这里建议直接通过类名进行访问~~
看看下面的代码:
public class Student {
public String name;
public int age;
public static String className;
public void show() {
System.out.println("班级:"+this.className);
}
public static void main(String[] args) {
Student student1 = new Student();
student1.className = "1班";
student1.show();
System.out.println("=============");
Student student2 = null;
student2.className = "2班";
System.out.println(Student.className);
System.out.println("=============");
Student.className = "3班";
System.out.println(Student.className);
}
}
为什么 student2 明明被置为null,却还是能进行对 className 进行使用赋值呢?
因为我们知道静态成员变量是不依赖对象的,所以 student2 也可以访问静态的成员变量className,但是就不能访问其他非静态的成员变量和成员方法了~~
static 修饰成员方法
被static修饰的成员方法也叫做静态成员方法,也可以叫做类方法,不是某个对象所特有的
public class Student {
public String name;
public int age;
public static String className;
public void doHomework(){
System.out.println(this.name+"做作业");
}
public void eat(){
System.out.println(this.name+"吃饭");
}
public static void test(){
System.out.println("考试");
}
public static void main(String[] args) {
test();
}
}
public class Test {
public static void main(String[] args) {
Student.test();
}
}
不同类里,我们可以通过 类名.方法 来进行调用该类的静态方法~~
但是不能在静态的方法里直接调用非静态的成员变量,因为静态方法是不依赖对象的,所以你要调用非静态方法只能先创建一个对象,然后再使用这个对象去调用非静态方法,也就意味着你在静态方法也是不能使用this关键字的(this关键字是依赖对象的~~)
非静态的成员方法是可以调用非静态成员方法的和静态成员方法的~
小结
一句话总结上面的:**静态成员方法和静态成员变量是不依赖对象的**
代码块
普通代码块
普通代码块:定义在方法中的代码块.
public class Test {
public static void main(String[] args) {
//Student.test();
{
int a = 10;
int b = 20;
}
}
}
这份代码里 { int a = 10; int b = 20; } 就是普通代码块~~
静态代码块
有 static 修饰的代码块,一般用于初始化静态成员变量~~
这个代码块在方法外面~~
public class Student {
public String name;
public int age;
public static String className;
//静态代码块
static{
className = "1班";
System.out.println(className);
}
}
实例化代码块(构造代码块)
定义在类中的代码块(不加修饰符)。也叫:实例代码块。构造代码块一般用于初始化实例成员变量。
也是在方法外面定义的~~
public class Student {
public String name;
public int age;
public static String className;
//实例化代码块
{
name = "张三";
age = 10;
}
}
public class Student {
public String name;
public int age;
public static String className;
//实例化代码块
name = "张三";
age = 10;
}
没有加{ }也可以是实例化代码块的,只要在方法的外面的代码都是实例化代码的组成部分,按照定义顺序依次执行,以上面的代码为例子,name先等于null,然后 age 等于10 ,className 等于 null,最后就是name = “张三”;age = 10;了~~
同步代码块
后面文章(多线程的内容)讲解~
执行顺序
先看现象:
运行结果:
静态代码块不管生成多少个对象,其只会执行一次
静态成员变量是类的属性,因此是在JVM加载类时开辟空间并初始化的
如果一个类中包含多个静态代码块,在编译代码时,编译器会按照定义的先后次序依次执行(合并)
实例代码块只有在创建对象时才会执行,如果有多个实例化代码块就会根据定义的先后次序执行
最后就是执行构造方法
简单来说:
静态代码块(只会执行一次)-----》 实例化代码块 ------》构造方法
包的访问权限
这里我会在下面的补充里面讲解到public,private,default这三个权限访问修饰符的含义和使用,protected和子类会在继承的文章中讲到~~
public
被 public 修饰的变量或者方法是公共的,在任何地方都能使用
private
被private 修饰的是私有的,只能在类内部使用
default
注意没有真实的 default 关键字,这个的中文意思有默认的,就是代表默认权限,就是没有修饰符修饰的时候会被默认成默认权限(default),在同一个包里面都能使用。
合理使用修饰符
Java中外面会将一些方法或者变量给封装起来,也就是使用上面这些修饰符进行封装,留下一些接口给外界使用~~
例如下面的代码:
public class Student {
private String name;
private int age;
private static String className;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public static String getClassName() {
return className;
}
public static void setClassName(String className) {
Student.className = className;
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
{
name = "张三";
age = 10;
System.out.println("执行实例化代码块");
}
static{
className = "1班";
System.out.println("执行静态代码块");
}
public Student(){
System.out.println("调用构造方法");
}
public void doHomework(){
System.out.println(this.name+"做作业");
}
public void eat(){
System.out.println(this.name+"吃饭");
}
public static void test(){
System.out.println("考试");
}
private static void main(String[] args) {
//this.name = 10;
Student student1 = new Student();
student1.eat();
test();
}
}
我们通过使用private将类里面的细节给封装起来,通过get…和set…或构造方法来进行初始化和在类外也能得到里面的成员的值。
对象的成员变量初始化
就地初始化
在定义变量的时候直接赋初始值
public class Student {
private String name = "张三";
private int age = 10;
private static String className = "1班";
public String getName() {
return name;
}
}
代码块初始化
我们可以使用静态代码块和实例化代码块进行初始化,上面讲代码的时候就使用到了,这里不做代码示例。
构造方法初始化
public class Student {
private String name;
private int age;
private static String className;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
}
快捷键写代码
我们上面提到get…和set…方法还有一个初始化成员变量的构造方法,在IDEA中我们可以快速生成,我们可以使用快捷键Alt+Insert或者右键找到Generate,Getter就是获取这个变量,Setter就是设置这个变量,Constructor可以设置构造方法,然后选择你想要的成员变量就可以了(按住Ctrl,就可以选择多个变量了),最后点击OK,代码就完成了~~
标签:
相关文章
最新发布
- 【Python】selenium安装+Microsoft Edge驱动器下载配置流程
- Python 中自动打开网页并点击[自动化脚本],Selenium
- Anaconda基础使用
- 【Python】成功解决 TypeError: ‘<‘ not supported between instances of ‘str’ and ‘int’
- manim边学边做--三维的点和线
- CPython是最常用的Python解释器之一,也是Python官方实现。它是用C语言编写的,旨在提供一个高效且易于使用的Python解释器。
- Anaconda安装配置Jupyter(2024最新版)
- Python中读取Excel最快的几种方法!
- Python某城市美食商家爬虫数据可视化分析和推荐查询系统毕业设计论文开题报告
- 如何使用 Python 批量检测和转换 JSONL 文件编码为 UTF-8
点击排行
- 版本匹配指南:Numpy版本和Python版本的对应关系
- 版本匹配指南:PyTorch版本、torchvision 版本和Python版本的对应关系
- Python 可视化 web 神器:streamlit、Gradio、dash、nicegui;低代码 Python Web 框架:PyWebIO
- 相关性分析——Pearson相关系数+热力图(附data和Python完整代码)
- Python与PyTorch的版本对应
- Anaconda版本和Python版本对应关系(持续更新...)
- Python pyinstaller打包exe最完整教程
- Could not build wheels for llama-cpp-python, which is required to install pyproject.toml-based proj