目录
3.2、利用IDEA添加setName() getName()方法
1、封装的概念
概念:对类内部的实现细节,进行了隐藏(封装),对外只提供了一些公开的接口,供其他的用户进行访问(如一个电脑,对电脑内部的CPU,电路板等隐藏,对外提供了键盘,usb接口等)
2、访问限定符
限定符:
private(私有的),default(默认权限),protected(受保护的),public(公开的)
注意:
- default并不是限定符,不加限定符就是默认权限,如String name,用default表示只是为了和其它三个限定符相对应,其实只有三个限定符。
访问权限:
3、封装
3.1、封装例子
说明:(看下面代码)
- 在Person类中,name被private修饰,要访问name只能在同一个包同一个类中进行
- 所以在同一个类Person中加了一个public setName()方法,就可以在另外的类Test中访问输入public setName()方法,再用该方法访问将输入值赋值给被private修饰的name。
- 在Test类中访问public getName(),用public getName()返回输入后的被private修饰的name。
- 最终实现封装,即不能直接对Person类中的private修饰的name(细节)操作,而只能对封装中的类提供的接口,public的方法进行操作
代码如下:
public class Test {
public static void main(String[] args) {
Person peo=new Person();
peo.setName("zhangsan"); //通过输入访问public setName,从而访问private name
//返回值name:zhangsan
String s=peo.getName(); //用public getName访问,得到返回值就是private name
System.out.println("返回值neme:"+s); //打印返回值
//name:zhangsan age:0
peo.show();
}
}
class Person{
private String name; //被private封装,只能在当前类中更改
public int age; //要访问private修饰的成员变量,可以再用一个public方法,从而可以外部访问
public void setName(String name){ //从main中输入数据访问
this.name=name;
}
public String getName(){ //直接返回当前name
return this.name;
}
public void show(){ //public修饰,可以从Test类中进行访问
System.out.println("name:"+name+" age:"+age);
}
}
结果展示:
返回值name:zhangsan
name:zhangsan age:0
3.2、利用IDEA添加setName() getName()方法
1、右键点击找到Generate
2、点击Generate,在根据自己的选则Getter和(或)Setter
3、点击,选择自己要添加setName()和getName()的成员变量
4、若都选,按住Ctrl,用鼠标都选住,按OK,完成!
4、包
4.1、包的概念
概念:
为了更好的管理类,把多个类收集在一起成为一组,称为软件包
例如:
在一个Java工程中,External Libraries路径下rt.jar路径下Java路径下的util就是一个工具包
注意:
1、src不是包,它表示源代码
2、一个工程中可能有相同名字的几个类,因为放在不同的包里就不会冲突
4.2、导入包中的类
1、import java.util.Date; //导入时间
获取一个毫秒级别时间戳:
import java.util.Date;
public class Test2 {
public static void main(String[] args) {
Date date = new Date();
System.out.println(date.getTime());
}
}
结果演示:
1659953710202
2、当需要util中的多个工具时:import java.util.*; //代码用到util中哪个工具,就会自己去调用
时间戳(Date)和数组(Arrays)
import java.util.*;
public class Test2 {
public static void main(String[] args) {
Date date = new Date();
//用到util中的Date
System.out.println(date.getTime());
int[] arr={1,2,3,4};
//用到util中的Arrays
System.out.println(Arrays.toString(arr));
}
}
结果演示:
1659954091964
[1, 2, 3, 4]
3、用import static导入静态的方法和字段
不用import static导入:
//不用import static 导入静态方法sqrt,pow
public class Test2 {
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);
}
}
用import static导入(很少用):
//用import static导入静态方法sqrt,pow
import static java.lang.Math.*;
public class Test2 {
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);
}
}
4.3、创建自定义包和类
4.3.1、在工程里创建自定义包
1、选住src(),点击右键,选择New路径下的Package
2、点击Package,输入你要的包名
3、按Enter键完成!
4.3.2、在包里创建类
1、选住包,点击右键,选择New路径下的Java Class
2、输入你要创建的类名
3、按Enter完成!
4.4、包的访问权限控制
private 包权限 protected public
1、由于默认权限范围是同一包中,所以又叫包权限
2、创建的类不放进自己新建的包里就进入默认包,1>、且默认包中可以实例化自己创建的包中的类。2>、但自己创建的包不能实例化默认包中的类。
4.5、常见的包
- java.lang:系统常用基础类(String、Object),此包从JDK1.1后自动导入。
- java.lang.reflflect:java 反射编程包;
- java.net:进行网络编程开发包。
- java.sql:进行数据库开发的支持包。
- java.util:是java提供的工具程序包。(集合类等) 非常重要
- java.io:I/O编程开发包。
5、static成员
1、访问方式:
有static 类名.类变量(类方法)
无static 对象名.成员变量(成员方法)
5.1、static修饰成员变量
1、static修饰成员变量
类中成员变量用static修饰,成员变量就在方法区,如public static classes,classes为静态成员变量,又叫类变量,它属于类(在方法区)或者说所以对象共享,不属于对象(堆)
2、初始化:
- 可以在类中直接赋值,即就地初始化。
- 静态成员变量是类的属性,因此是在JVM加载类时开辟空间并初始化。
- 如果静态成员变量被private修饰,应该就地初始化,并用静态方法访问。
5.2、static修饰成员方法
规则:
1. 不属于某个具体的对象,是类方法2. 不能在静态方法中访问任何非静态成员变量3. 不能在 静态方法中调用任何非静态方法,因为非静态方法有 this 参数,在静态方法中调用时候无法传递 this 引用4、静态方法无法重写,不能用来实现多态(多态部分讲解)应用:静态方法访问类变量(静态成员变量)
静态方法访问类变量:
class Student{ // ...
private static String classRoom = "xrcfadm";
// ...
public static String getClassRoom(){ //静态方法访问类变量classRoom
return classRoom;
}
}
public class Test2 {
public static void main(String[] args) {
System.out.println(Student.getClassRoom());
}
}
结果演示
xrcfadm
5.3、static成员变量初始化
1、就地初始化:在类中直接赋值
2、静态代码块初始化
3、也可以在main中直接赋值(前提是不用private作限制),格式为:类名.类变量 = ...
6、代码块
6.1、代码块概念及分类
概念:
使用{}定义的一段代码称为代码块
分类:
普通代码块,构造块,静态块,同步代码块(多线程部分)
6.2、普通代码块
普通代码块:定义在方法中的代码块。这种方法比较少见。
public class Test2{
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
6.3、构造代码块
构造块:定义在类中的代码块,也叫实例代码块
作用:初始化实例(无static)成员变量
class Student{
//实例成员变量
private String name;
private int age;
public Student() {
System.out.println("I am Student init()!");
}
//实例代码块
{
this.name = "xrcf";
this.age = 18;
System.out.println("I am instance init()!");
}
public void show(){
System.out.println("name: "+name+" age: "+age);
}
}
public class Test2 {
public static void main(String[] args) {
Student stu = new Student();
stu.show();
}
}
结果演示:
I am instance init()!
I am Student init()!
name: xrcf age: 18
6.4、静态代码块
静态块:使用static定义的代码块
作用:初始化静态成员变量
初始化静态成员变量:
class Student{
private static String classRoom;
//静态代码块
static {
classRoom = "bit306";
System.out.println("I am static init()!");
}
//构造方法
public Student(){
System.out.println("I am Student init()!");
}
public static void main(String[] args) {
Student s1 = new Student();
Student s2 = new Student();
}
}
结果演示:
I am static init()!
I am Student init()!
I am Student init()!
6.5、代码块注意:
1、静态代码块不管生成多少个对象,其只会执行一次
2、实例代码块只有在创建对象时才会执行3、静态成员变量(静态代码块)是类的属性,因此是在 JVM 加载类时开辟空间并初始化的4、顺序是:静态代码块 --> 实例代码块 --> 不带参数的构造方法5、如果一个类中包含多个静态代码块,在编译代码时,编译器会按照定义的先后次序依次执行 ( 合并 )
7、内部类
概念:
在Java中,1、内部类:将一个类定义在另一个类的内部,这个类叫做内部类。
2、外部类:一般的类。内部类也是封装的一种体现。
分类:1、实例内部类,2、静态内部类,局部内部类,匿名内部类
7.1、实例内部类
概念:未被static修饰的成员内部类
7.1.1、如何获取实例内部类的对象?
OutClass.InClass inClass = new OutClass().new InClass();
颜色1、表示inClass的类型
颜色2、表示外部类,加上.(点)表示引用
颜色3、表示新建内部类对象
代码如下:
package inner;
public class Test {
public static void main(String[] args) {
//获取内部类对象
//法一
OutClass outClass = new OutClass(); //先得到outClass对象
OutClass.InClass inClass = outClass.new InClass(); //用outClass对象引用new inClass对象得到内部类对象
//法二 //OutClass.InClass是它的类型
OutClass.InClass inClass2 = new OutClass().new InClass();
}
}
//外部类
class OutClass{
public int data1=1;
int data2=2;
public static int data3=3;
public void func(){
System.out.println("OutClass::func()");
}
/**
* 1、如何获取实例内部类的对象
*
*/
//实例内部类
class InClass{
public int data4=4;
int data5=5;
//public static int data6=6;//实例内部类中不能有静态成员
public void func(){
System.out.println("InClass::func()");
}
}
}
7.1.2、实例内部类中不能有静态成员
原因:因为实例内部类中static修饰的成员,会在外部类加载时就执行,而内部类在后执行,就出错了。代码看7.1.1。
1、如果非要有那就用static final(表示常量)修饰,如:在实例内部类中:public static final int data6=6;但date6仍在类变量所在的方法区,与是否有final无关
2、常量是在程序编译的时候确定的,一经初始化,就不能再修改。若在外部类定义常量:
final int SIZE = 10; ,就不可再修改,SIZE在JVM中的常量池
7.1.3、实例内部类中如何获取外部类相同的成员变量?
1、若是内外部类中的成员变量重名,在内部类中一般只能使用内部类的成员变量。(就近原则)dian
2、若要在实例内部类中获取外部类的重名成员变量:
1>外部类名+(点)this+.(点)+成员变量 2>在实例内部类中new一个外部类,再去访问外部类成员变量。代码如下
代码如下:
package inner;
public class Test {
public static void main(String[] args) {
OutClass.InClass inClass = new OutClass().new InClass(); //实例内部类要先实例化才能调用
inClass.func();
}
}
//外部类
class OutClass{
public int data1=1;
public void func(){
System.out.println("OutClass::func()");
}
//实例内部类
class InClass{
public int data1=11;
public void func(){
//法一
System.out.println(OutClass.this.data1);//从内部类访问外部类的成员变量
//法二
OutClass outClass = new OutClass();//先new一个外部类
System.out.println(outClass.data1);
System.out.println(InClass.this.data1); //内部类访问内部类成员变量
System.out.println("InClass::func()");
}
}
}
结果演示:
1
1
11
InClass::func()
7.1.5、外部类访问实例内部类
1>要先实例化外部类对象,2>再用外部类对象访问外部类方法,3>再在用方法中实例化内部类,4>最后在方法中的内部类对象访问内部类。
代码如下:
package inner;
public class Test {
public static void main(String[] args) {
OutClass outClass = new OutClass(); //1>先new一个外部类对象
outClass.outfunc(); //2>再通过外部类对象访问外部方法
}
}
//外部类
class OutClass{
public int data1=1;
public void func(){
System.out.println("OutClass::func()");
}
//实例内部类
class InClass{
public int data1=11;
public void func() {
System.out.println(InClass.this.data1); //内部类访问内部类成员变量
System.out.println("InClass::func()");
}
}
public void outfunc(){
System.out.println("OutClass::func()");
InClass inClass = new InClass(); //3>先new一个实例内部类
inClass.func();//4>
}
}
结果演示:
OutClass::func()
11
InClass::func()
7.1.6、实例内部类注意事项
1. 外部类中的任何成员都可以在实例内部类方法中直接访问2.实例内部类所处的位置与外部类成员位置相同,因此也受 public 、 private 等访问限定符的约束3. 在实例内部类方法中访问同名的成员时,优先访问自己的,如果要访问外部类同名的成员,必须:外部类名 称 .this. 同名成员 来访问4. 实例内部类对象必须在先有外部类对象前提下才能创建5. 实例内部类的非静态方法中包含了一个指向外部类对象的引用6. 外部类中,不能直接访问实例内部类中的成员,如果要访问必须先要创建内部类的对象。
7.2、静态内部类
7.2.1、如何获取静态内部类对象?
OutClass.InClass inClass = new OutClass.InClass();
颜色1:表示inClass的类型
颜色2:表示直接new一个静态内部类对象(不用实例化外部类对象)
7.2.2、静态内部类访问成员变量
静态内部类可以访问:
1、内部类的所有成员变量+外部类静态成员变量(即不能访问外部类非静态成员变量)
2、外部内非静态成员的访问,需要通过外部类对象的引用来访问
3、若非要访问,则先在内部类的方法中new一个外部类对象,再进行访问
7.2.3、静态内部类注意事项
1. 在静态内部类中只能访问外部类中的静态成员2. 创建静态内部类对象时,不需要先创建外部类对象
7.3、局部内部类(基本不用)
概念:即在方法中的类
缺陷:只能在该方法中使用,不能被public等修饰
字节码文件名:
内部类:外部类+$+内部类.class
局部内部类:外部类+$+数字+内部类.class
7.4、匿名内部类
new OutClass();匿名对象,只能用一次
new person { //匿名内部类(后续接口细讲)
};
8、对象的打印
8.1、toString打印对象
若直接输出,不用toString方法,结果是:inner.Person@1b6d3586(代表全路径)@后面的值是一个地址,是经过哈希变换得来的。
代码如下:
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;
}
//若没有这一段返回值结果是:inner.Person@1b6d3586
@Override //检查我们写的toString是否正确
public String toString() {
//这一步可以return自己定
return "[" + name + "," + gender + "," + age + "]";
}
//main方法在哪就从哪开始执行
public static void main(String[] args) {
Person person = new Person("Jim","男", 18);
System.out.println(person);
}
}
结果演示:
[Jim,男,18]
8.2、IDEA创建toString对象方法
1、右键,找到Generate
2、点击Generate,找到toString
3、点击toString,选择参数(一般是自动选择)
4、点击OK就完成!