这里写目录标题
一、封装
1.封装的概念
2.访问限定符
【说明】
- protected主要是用在继承中,继承部分详细介绍
- default权限指:什么都不写时的默认权限,只能在本包中类访问
- public权限:可以被任何其它类访问
- private权限:只能在当前类中访问,不能被其它类访问
- 访问权限除了可以限定类中成员的可见性,也可以控制类的可见性 (但可以修饰类的权限只有两种,一种是默认,另一种是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 class Test {
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类中访问,不能被其他类访问
}
}
【注意】
3.封装扩展之包
3.1包的概念
3.2导入包中的类
3.2.1Java 中已经提供了很多现成的类供我们使用. 例如Date类:可以使用 java.util.Date 导入 java.util 这个包中的 Date类
public static void main(String[] args) {
java.util.Date date=new java.util.Date();
System.out.println(date.getTime());
}
3.2.2使用 import语句导入包.比3.2.1方便
import java.util.Date;
public class Test {
public static void main(String[] args) {
Date date = new Date();
// 得到一个毫秒级别的时间戳
System.out.println(date.getTime());
}
}
import java.util.*;
public class Test {
public static void main(String[] args) {
Date date = new Date();
// 得到一个毫秒级别的时间戳
System.out.println(date.getTime());
}
}
但是我们更建议显式的指定要导入的类名. 否则还是容易出现冲突的情况
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());
}
}
// 编译出错
Error:(5, 9) java: 对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());
}
}
3.2.3使用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);
}
}
3.3 自定义包
1.基本规则
2.操作步骤
(1)在 IDEA 中先新建一个包: 右键 src -> 新建 -> package
(2)在弹出的对话框中输入包名, 例如 com.bit.demo1
(3) 在包中创建类, 右键包名 -> 新建 -> 类, 然后输入类名即可.
(4)此时可以看到我们的磁盘上的目录结构已经被 IDEA 自动创建出来了
(5)同时我们也看到了, 在新创建的 TestDemo1.java 文件的最上方, 就出现了一个 package 语句
3.4包的访问权限控制
//TestDemo1.java
package com.bit.demo1;
public class TestDemo1 {
int a=1;//成员变量 默认访问权限 包访问权限
public int b=111; //
private int c=999; //类访问权限
public static void main(String[] args) {
TestDemo1 testDemo1=new TestDemo1();
System.out.println(testDemo1.a);
System.out.println(testDemo1.b);
System.out.println(testDemo1.c);
}
}
- 在和TestDemo同一包下的TestDemo2文件中访问访问3个变量
package com.bit.demo1;
public class TestDemo2 {
public static void main(String[] args) {
TestDemo1 testDemo1=new TestDemo1();
System.out.println(testDemo1.a);
System.out.println(testDemo1.b);
//System.out.println(testDemo1.c);err
//不能访问c,因为c被private修饰,只能在其定义的类中访问
}
}
- 在和TestDemo1处在不同包中的TestDemo3中访问3个变量
package com.bit.demo2;
import com.bit.demo1.TestDemo1;
public class TestDemo3 {
public static void main(String[] args) {
TestDemo1 testDemo1=new TestDemo1();
//System.out.println(testDemo1.a); err
//a是包访问权限,只能在同一个包中访问
System.out.println(testDemo1.b);
//System.out.println(testDemo1.c);err
//c是类访问权限,只能在其被定义的类中访问
}
}
3.5常见的包
二、static关键字
1.引入static
class Student{
public String name;
public int age;
public double score;
public Student(String name, int age, double score) {
this.name = name;
this.age = age;
this.score = score;
}
}
public class Test1 {
public static void main(String[] args) {
Student student1 =new Student("zhang",19,89.0);
Student student2=new Student("lisi",99,99.0);
System.out.println("jajajja");
}
}
学生student1和student2
【补充】:
2.static修饰成员变量
class Student{
public String name;
public int age;
public double score;
static String classes;
public Student(String name, int age, double score) {
this.name = name;
this.age = age;
this.score = score;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", score=" + score +",classes="+classes+
'}';
}
}
public class Test1 {
public static void main(String[] args) {
Student student1 =new Student("zhang",19,89.0);
Student student2=new Student("lisi",99,99.0);
Student.classes="Java1班";
System.out.println(student1.toString());
System.out.println(student2.toString());
}
}
执行结果
两个对象所打印出来的班级是同一个班级,说明classes被这两个对象共享了。
我们可以看到在访问静态成员变量的时候,不需要通过对象的引用去访问,可直接通过类名来访问这也证明了静态成员变量不属于某个具体的对象,是所有对象所共享的。
【注意】
通过对象的引用也可以访问静态成员变量(可以但不推荐)
- 解析下面这段代码
public static void main(String[] args) {
Student student=null;
student.classes="Java1";
System.out.println(student.classes);
//执行结果 Java1
}
- 普通成员方法中可以使用静态成员变量
class Student{
public String name;
public int age;
public double score;
static String classes;
public Student(String name, int age, double score) {
this.name = name;
this.age = age;
this.score = score;
}
public void doClass(){
System.out.println(this.name+" 正在上课 "+"班级:"+classes);
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", score=" + score +",classes="+classes+
'}';
}
}
public class Test1 {
public static void main(String[] args) {
Student student1 =new Student("zhang",19,89.0);
Student.classes="Java1班";
student1.doClass();
}
}
//执行结果 zhang 正在上课 班级:Java1班
- 静态方法中不能访问非静态的成员(下面的static修饰成员方法中详细说明)
【类变量的特性补充】
3.static修饰成员方法
public static void func(){
System.out.println("这是一个静态方法");
}
public static void main(String[] args) {
Student.func();
}
//执行结果:这是一个静态方法
通过类名来直接调用静态方法
【静态方法特性】
- 不属于某个具体的对象,是类方法
- 可以通过对象调用,也可以通过类名.静态方法名(…)方式调用,更推荐使用后者
- 静态方法没有隐藏的this引用参数,因此不能在静态方法中访问任何非静态成员变量
- 静态方法中不能调用任何非静态方法,因为非静态方法有this参数,在静态方法中调用时候无法传递this引用
4.static成员变量初始化
4.1 静态初始化
就地初始化指的是:在定义时直接给出初始值
public class Student{
private String name;
private String gender;
private int age;
private double score;
private static String classRoom = "Bit306";
// ...
}
4.2 静态代码块初始化
在下面的代码块中会详细说
【注意】:
三、 代码块
1.代码块的概念及其分类
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.实例代码块
class Student{
public String name;
public int age;
public double score;
public static String classes;
{
System.out.println("实例代码块!!一般用来初始化实例成员变量");
}
public Student(String name, int age, double score) {
this.name = name;
this.age = age;
this.score = score;
System.out.println("调用带有三个参数的构造方法");
}
public void doClass(){
System.out.println(this.name+" 正在上课 "+"班级:"+classes);
}
public static void func(){
System.out.println("这是一个静态方法");
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", score=" + score +",classes="+classes+
'}';
}
}
public class Test1 {
public static void main(String[] args) {
Student student=new Student("bit",19,89.9);
}
}
先分析上面的代码
执行结果:
4.静态代码块
class Student{
public String name;
public int age;
public double score;
public static String classes;
{
System.out.println("实例代码块!!一般用来初始化实例成员变量");
}
static {
System.out.println("这是一个静态代码块");
}
public Student(String name, int age, double score) {
this.name = name;
this.age = age;
this.score = score;
System.out.println("调用带有三个参数的构造方法");
}
public void doClass(){
System.out.println(this.name+" 正在上课 "+"班级:"+classes);
}
public static void func(){
System.out.println("这是一个静态方法");
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", score=" + score +",classes="+classes+
'}';
}
}
public class Test1 {
public static void main(String[] args) {
Student student=new Student("bit",19,89.9);
}
}
这段代码相对于上面实力代码块的那段代码,只添加了一个静态代码块
执行结果:
分析代码
【注意】
- 静态代码块不管生成多少个对象,其只会执行一次
//在main函数中实例化了两个对象
public static void main(String[] args) {
Student student1=new Student("bit",19,89.9);
Student student2=new Student("bit2",16,89.9);
}
执行结果:
我们发现静态代码块只执行了一次
-
如果一个类中定义了多个静态代码块,那么执行的顺序和他们定义的先后有关,定义在前面的先执行
-
静态成员变量是类的属性,因此是在JVM加载类时开辟空间并初始化的
- 只要访问了静态成员变量,都会优先将静态代码块执行一遍
class Student1{
public String name;
public int age;
public double score;
public static String classes;
{
System.out.println("实例代码块!!一般用来初始化实例成员变量");
}
static {
classes="Java1";
System.out.println("这是一个静态代码块");
}
}
public class Test2 {
public static void main(String[] args) {
System.out.println(Student1.classes);
}
}
执行结果:
- 静态代码块中不能访问非静态成员变量和方法,因为非静态成员变量和方法以来对象。