Java学习DAY8~类和对象(二)~2021.01.18

5. 包

包 (package) 是组织类的一种方式.

5.1 导入包中的类

Java 中已经提供了很多现成的类供我们使用. 例如:
可以使用 java.util.Date 这种方式引入 java.util 这个包中的 Date 类.

import java.util.Date;
public class Test {
public static void main(String[] args) {
Date date = new Date();
// 得到一个毫秒级别的时间戳
System.out.println(date.getTime());
}
}

5.2 包的访问权限控制

private/ public 这两个关键字表示 “访问权限控制” .
被 public 修饰的成员变量或者成员方法, 可以直接被类的调用者使用.
被 private 修饰的成员变量或者成员方法, 不能被类的调用者使用.

  • 直接使用 public
class Person {
public String name = "张三";
public int age = 18;
}
class Test {
public static void main(String[] args) {
Person person = new Person();
System.out.println("我叫" + person.name + ", 今年" + person.age + "岁");
}
}
// 执行结果
我叫张三, 今年18

这样的代码导致类的使用者(main方法的代码)必须要了解 Person 类内部的实现, 才能够使用这个类. 学习成本较高。一旦类的实现者修改了代码(例如把 name 改成 myName), 那么类的使用者就需要大规模的修改自己的代码, 维护成本较高.

  • 使用 private 修饰属性, 并提供 public 方法供类的调用者使用.
class Person {
private String name = "张三";
private int age = 18;
public void show() {
System.out.println("我叫" + name + ", 今年" + age + "岁");
}
}
class Test {
public static void main(String[] args) {
Person person = new Person();
//当属性被private修饰之后,类外就不可以访问了。
//System.out.println("我叫" + person.name + ", 今年" + person.age + "岁");
person.show();
}
}
// 执行结果
我叫张三, 今年18

当属性被private修饰之后,类外不可以直接进行访问。
此时字段已经使用 private 来修饰. 类的调用者(main方法中)不能直接使用. 而需要借助 show 方法.
此时类的使用者就不必了解 Person 类的实现细节.
同时如果类的实现者修改了字段的名字, 类的调用者不需要做出任何修改(类的调用者根本访问不到name, age 这样的字段)

6.代码块

使用{ } 定义的一段代码.
根据代码块定义的位置以及关键字,又可分为以下四种:

6.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

6.2 构造块

构造块:定义在类中的代码块(不加修饰符)。也叫:实例代码块。构造代码块一般用于初始化实例成员变量

class Person{
private String name;//实例成员变量
private int age;
private String sex;
public Person() {
System.out.println("I am Person init()!");
}
//实例代码块
{
this.name = "bit";
this.age = 12;
this.sex = "man";
System.out.println("I am instance init()!");
}
public void show(){
System.out.println("name: "+name+" age: "+age+" sex: "+sex);
}
}
public class Main {
public static void main(String[] args) {
Person p1 = new Person();
p1.show();
}
}
// 运行结果
I am instance init()!
I am Person init()!
name: bit age: 12 sex: man

注意事项: 实例代码块优先于构造函数执行。

6.3 静态块

使用static定义的代码块。一般用于初始化静态成员属性。

class Person{
private String name;//实例成员变量
private int age;
private String sex;
private static int count = 0;//静态成员变量 由类共享数据 方法区
public Person(){
System.out.println("I am Person init()!");
}
//实例代码块
{
this.name = "bit";
this.age = 12;
this.sex = "man";
System.out.println("I am instance init()!");
}
//静态代码块
static {
count = 10;//只能访问静态数据成员
System.out.println("I am static init()!");
}
public void show(){
System.out.println("name: "+name+" age: "+age+" sex: "+sex);
}
}
public class Main {
public static void main(String[] args) {
Person p1 = new Person();
Person p2 = new Person();//静态代码块是否还会被执行?
}
}

注意事项

  • 静态代码块不管生成多少个对象,其只会执行一次,且是最先执行的。
  • 静态代码块执行完毕后, 实例代码块(构造块)执行,再然后是构造函数执行。

6.4同步代码块

7. 访问限定符

  • Java 中对于字段和方法共有四种访问权限:
  1. private: 类内部能访问, 类外部不能访问
  2. 默认(也叫包访问权限): 类内部能访问, 同一个包中的类可以访问, 其他类不能访问.
  3. protected: 类内部能访问, 子类和同一个包中的类可以访问, 其他类不能访问.
  4. public : 类内部和类的调用者都能访问
    在这里插入图片描述
  • 对于类的调用者来说, protected 修饰的字段和方法是不能访问的,对于类的 子类 和 同一个包的其他类 来说, protected 修饰的字段和方法是可以访问的。
// Animal.java
public class Animal {
protected String name;
public Animal(String name) {
this.name = name;
}
public void eat(String food) {
System.out.println(this.name + "正在吃" + food);
}
}
// Bird.java
public class Bird extends Animal {
public Bird(String name) {
super(name);
}
public void fly() {
// 对于父类的 protected 字段, 子类可以正确访问
System.out.println(this.name + "正在飞 ︿( ̄︶ ̄)︿");
}
}
// Test.java 和 Animal.java 不在同一个 包 之中了.
public class Test {
public static void main(String[] args) {
Animal animal = new Animal("小动物");
System.out.println(animal.name); // 此时编译出错, 无法访问 name
}
}

8. 内部类

  • 在 Java 中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。
  • 广泛意义上的内部类一般来说包括这四种:

8.1 静态内部类(内部类前面用 static )

定义:

public class Test {
static class B{
}
}

和静态变量、静态方法类似,静态内部类也是和当前类(Test)绑定。
使用时,也是通过Test类来调用,如

public class Test {
static class B{
}
public static void main(String[] args) {
B b1 = new Test.B();
//在当前类Test中使用时,和静态变量,静态方法类似,也可以把Test.B()省略写为B()
B b2 = new B();
}
}

8.2 匿名内部类(相对比较常用)

匿名内部类的定义,是在一个方法或是代码块中定义的类,并且没有显示申明类的名称,比如这样:

public class Test {
public static void main(String[] args) {
//定义了一个匿名内部类
A a = new A(){
};
}
}
class A{
}

匿名内部类是使用的非常多的一种内部类,和A a = new A(); 这样的实例操作不同,后边还有一个大括号,表示可以重写方法,其实是定义了另外一个类(没有显示的类名,所以叫匿名)。经常用在需要实例化某个对象,但需要重写方法时,比如new接口,抽象类就是使用匿名内部类较多的方式。

public class Test {
public static void main(String[] args) {
//定义了一个匿名内部类
X x = new X(){
@Override
public void callback() {
}
};
}
}
interface X{
void callback();
}

8.3 成员内部类

是作为对象的一个成员来定义的类:

public class Test {
class C{
}
}

和成员变量、实例方法类似,成员内部类也是和当前类的实例对象绑定的,类似Test类对象的成员。需要通过对象来使用:

public class Test {
public static void main(String[] args) {
C c = new Test().new C();
}
class C{
}
}

8.4 局部内部类

局部内部类的作用域也是和局部变量类似,是在方法或是代码块中定义。这点和匿名内部类的作用域一样:

public class Test {
public static void main(String[] args) {
class D extends A{
}
System.out.println(new D());
}
}
class A{
}

9.常见面试题

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值