六、包
面向对象体系,为了更好的管理类,把多个类收集在一起成为一组,称为软件包。
在Java中也引入了包,包是对类、接口等的封装机制的体现,是一种对类或者接口等的很好的组织方式。包还有一个重要的作用:在同一个工程中允许存在相同名称的类,只要处在不同的包中即可 。
(一)导入包中的类
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 static导入包中静态的方法和字段。例如求平方以及平方根的时候,静态导入就会更方便一些。
import static java.lang.Math.*;
public class Test {
public static void main(String[] args) {
double x = 3;
double y = 4;
double result1 = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
double result2 = sqrt(pow(x, 2) + pow(y, 2));
System.out.println(result);
}
}
(二)自定义包
在文件的最上方加上一个package语句指定该代码在哪个包中。包名需要尽量指定成唯一的名字,通常会用公司的域名的颠倒形式(例如com.bit.demo1)。
包名要和代码路径相匹配。例如创建com.bit.demo1的包,那么会存在一个对应的路径com/bit/demo1来存储代码。如果一个类没有package语句,则该类被放到一个默认包中。
七、static成员
(一)静态成员变量
static修饰的成员变量,称为静态成员变量,不属于某个具体的对象,是所有对象所共享的。
class Student{
public String name;
public int age;
public static String classRoom = "106";
public static void main(String[] args) {
// 静态成员变量可以直接通过类名访问
System.out.println(Student.classRoom);
Student s = new Student();
// 也可以通过对象访问:但是classRoom是共享的
System.out.println(s.classRoom);
}
}
静态成员变量特性
1.不属于某个具体的对象,是类的属性,所有对象共享的,不存储在某个对象的空间中
2.既可以通过对象访问,也可以通过类名访问,但一般更推荐使用类名访问
3.类变量存储在方法区当中
4.生命周期伴随类的一生(随类的加载而创建,随类的卸载而销毁)
(二)静态成员方法
Java中,被static修饰的成员方法称为静态成员方法,是类的方法,不是某个对象所特有的。静态成员一般是通过静态方法来访问的。
class Student {
private static String classRoom = "106";
public static String getClassRoom() {
return classRoom;
}
}
public class TestStudent {
public static void main(String[] args) {
System.out.println(Student.getClassRoom());
}
}
静态方法特性
1.不属于某个具体的对象,是类方法
2.可以通过对象调用,也可以通过类名.静态方法名(...)方式调用,更推荐使用后者
3.不能在静态方法中访问任何非静态成员变量
4.静态方法中不能调用任何非静态方法,因为非静态方法有this参数,在静态方法中调用时候无法传递this引用
5.静态方法无法重写,不能用来实现多态。
(三)static成员变量初始化
注意:静态成员变量一般不会放在构造方法中来初始化,构造方法中初始化的是与对象相关的实例属性。静态成员变量的初始化分为两种:就地初始化和静态代码块初始化。就地初始化指的是在定义时直接给出初始值。
八、代码块
使用{}定义的一段代码称为代码块。根据代码块定义的位置以及关键字,又可分为四种:
(一)普通代码块
定义在方法中的代码块,这种用法较少见。
public class Main {
public static void main(String[] args) {
{
int x = 10;
System.out.println(x);
}//普通方法块
int x = 100;
System.out.println(x);
}
}
(二)构造代码块
定义在类中的代码块(不加修饰符),也叫实例代码块。一般用于初始化实例成员变量。
class Student {
public String name;
public int age;
{
this.name = "bit";
this.age = 12;
}//实例代码块
}
(三)静态代码块
使用static定义的代码块称为静态代码块。一般用于初始化静态成员变量。
class Student {
public static String classRoom;
static {
classRoom = "106";
System.out.println(classRoom);
}// 静态代码块
}
(四)同步代码块
九、内部类
当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服务,那么整个内部的完整结构最好使用内部类。在Java中,可以将一个类定义在另一个类或者一个方法的内部,前者称为内部类,后者称为外部类。内部类也是封装的一种体现。
根据内部类定义的位置不同,一般可以分为以下几种形式:
1.成员内部类(普通内部类:未被static修饰的成员内部类和静态内部类:被static修饰的成员内部类)
2.局部内部类(不谈修饰符)、匿名内部类
public class OutClass {// OutClass是外部类
class InnerClass{// InnerClass是内部类
}
}
注意事项
1.定义在class类名{}花括号外部的,即使是在一个文件里,都不能称为内部类
2.内部类和外部类共用同一个java源文件,但是经过编译之后,内部类会形成单独的字节码文件
根据内部类定义的位置不同,一般可以分为以下几种形式:
1.成员内部类:实例内部类和静态内部类/非实例内部类
2.局部内部类(不谈修饰符)、匿名内部类
(一)实例内部类
未被static修饰的成员内部类
class OutClass {
class InnerClass {
}
}
public class TestOutClass {
public static void main(String[] args) {
// 要访问实例内部类中成员,必须要创建实例内部类的对象,需要借助外部类创建实例内部类对象
OutClass.InnerClass innerClass1 = new OutClass().new InnerClass();
// 也可以先创建外部类对象,再创建实例内部类对象
OutClass outClass = new OutClass();
OutClass.InnerClass innerClass2 = outClass.new InnerClass();
}
}
注意事项
1.外部类中的任何成员都可以在实例内部类方法中直接访问
2.实例内部类所处的位置与外部类成员位置相同,因此也受public、private等访问限定符的约束
3.在实例内部类方法中访问同名的成员时,优先访问自己的,如果要访问外部类同名的成员,必须:外部类名称.this.同名成员来访问
4.实例内部类对象必须在先有外部类对象前提下才能创建
5.实例内部类的非静态方法中包含了一个指向外部类对象的引用
6.外部类中,不能直接访问实例内部类中的成员,如果要访问必须先要创建内部类的对象。
(二)静态内部类/非实例内部类
被static修饰的内部成员类称为静态内部类
class OutClass {
static class InnerClass {
}
}
public class TestOutClass {
public static void main(String[] args) {
OutClass.InnerClass innerClass = new OutClass.InnerClass();
}
}
注意事项
1. 在静态内部类中只能访问外部类中的静态成员,若想访问,则要先创建一个外部类的实例
2. 创建静态内部类对象时,不需要先创建外部类对象
(三)局部内部类
定义在外部类的方法体或者{}中,该种内部类只能在其定义的位置使用,一般使用的非常少。
public class OutClass {
class InnerClass{
public void method(){
}
}
}
注意事项
1.局部内部类只能在所定义的方法体内部使用
2.不能被public、static等修饰符修饰
3.编译器也有自己独立的字节码文件,命名格式:外部类名字$内部类名字.class
(四)匿名内部类
十、对象的打印
class Student{
public String name= "LEO7NARDO";
public int age=18;
}
public class Test {
public static void main(String[] args) {
Student stu = new Student();
System.out.println(stu);
}
}
此时打印出Student@1b6d3586
它是全路径@真实地址的哈希值,这个值是唯一的,可以被认为是地址。
如果想自定义输出,就要重写toString方法。快捷键是alt+insert,可以自动生成重写过后的toString方法。当然也可以自定义其他输出形式。
class Student{
public String name= "LEO7NARDO";
public int age=18;
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class Test {
public static void main(String[] args) {
Student stu = new Student();
System.out.println(stu);
}
}
此时打印Student{name='LEO7NARDO', age=18}。