面向对象有3个比较重要的思想:封装、继承、多态(也叫OPP语言对的三大特征)
今天我们主要讲封装
封装
封装的定义
封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互
访问限定修饰符
Java中主要通过类和访问权限来实现封装:类可以将数据以及封装数据的方法结合在一起,更符合人类对事物的认知,而访问权限用来控制方法或者字段能否直接在类外使用。Java中提供了四种访问限定符:
Num | 访问范围 | private | default(默认) | protected | public |
---|---|---|---|---|---|
1 | 同一包中同一个类 | √ | √ | √ | √ |
2 | 同一包中的其他类 | √ | √ | √ | |
3 | 不同包中的子类 | √ | √ | ||
4 | 不同包中的非子类 | √ |
private String name;//狗的名字
private int age;//狗的年龄
private String color;//狗的颜色
再使用set()方法 和 get()方法去访问成员变量
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 String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
这样IDEA就会为我们自动生成代码了
建包
这时候我们就创建好了
大多数时候字段使用private来修饰,方法使用public来修饰
常见的包
- java.lang:系统常用基础类(String、Object),此包从JDK1.1后自动导入。
- java.lang.reflect:java 反射编程包;
- java.net:进行网络编程开发包。
- java.sql:进行数据库开发的支持包。
- java.util:是java提供的工具程序包。(集合类等) 非常重要
- java.io:I/O编程开发包。
static成员
s
t
a
t
i
c
修饰的拿类名去访问,拿变量名去访问也可以但是非常不推荐!!!(不符合语法)
\color{red}{static修饰的拿类名去访问,拿变量名去访问也可以但是非常不推荐!!!(不符合语法)}
static修饰的拿类名去访问,拿变量名去访问也可以但是非常不推荐!!!(不符合语法)
s
t
a
t
i
c
修饰的拿类名去访问,拿变量名去访问也可以但是非常不推荐!!!(不符合语法)
\color{red}{static修饰的拿类名去访问,拿变量名去访问也可以但是非常不推荐!!!(不符合语法)}
static修饰的拿类名去访问,拿变量名去访问也可以但是非常不推荐!!!(不符合语法)
s
t
a
t
i
c
修饰的拿类名去访问,拿变量名去访问也可以但是非常不推荐!!!(不符合语法)
\color{red}{static修饰的拿类名去访问,拿变量名去访问也可以但是非常不推荐!!!(不符合语法)}
static修饰的拿类名去访问,拿变量名去访问也可以但是非常不推荐!!!(不符合语法)
静态变量就定义在成员变量的位置
\color{red}{静态变量就定义在成员变量的位置}
静态变量就定义在成员变量的位置
静态变量就定义在成员变量的位置
\color{red}{静态变量就定义在成员变量的位置}
静态变量就定义在成员变量的位置
静态变量就定义在成员变量的位置
\color{red}{静态变量就定义在成员变量的位置}
静态变量就定义在成员变量的位置
静态方法就定义在成员方法的位置
\color{red}{静态方法就定义在成员方法的位置}
静态方法就定义在成员方法的位置
静态方法就定义在成员方法的位置
\color{red}{静态方法就定义在成员方法的位置}
静态方法就定义在成员方法的位置
静态方法就定义在成员方法的位置
\color{red}{静态方法就定义在成员方法的位置}
静态方法就定义在成员方法的位置
创建一个学生类
Student类
public class Student {
public String classes;
public String name;
public Student(String classes, String name) {
this.classes = classes;
this.name = name;
}
}
Test类
public class Test {
public static void main(String[] args) {
Student student1 = new Student("1班","阿漓");
Student student2 = new Student("1班","阿欢");
}
}
试想一下现在这个一班一共有50人,这50人都在一班,那么我们需要50遍“一班”,这样去做非常麻烦,于是就有了static来解决这个麻烦
此时代码变动一下
public class Student {
public static String classes = "1班";
public String name;
public Student(String name) {
this.name = name;
}
}
public class Test {
public static void main(String[] args) {
Student student1 = new Student("阿漓");
Student student2 = new Student("阿欢");
}
}
这回通过调用Test,Student类是如何存储的呢?请看下图
如果确定一直都是1班,那么我们可以将班级写成常量拿final进行修饰
public static final String classes = "1班";
关于方法的执行顺序:
- 先执行静态的【只会执行一次】
- 再执行实例的
- 再执行构造方法的
内部类
就是在类当中再去定义一个类
1、实例内部类
即未被static修饰的成员内部类
//外部类
class OuterClass {
public int data1 = 1;
private int data2 = 2;
public static int data3 = 3;
public OuterClass() {
System.out.println("外部类的构造方法!");
}
// 内部类
class InnerClass {
public int data1 = 1111;
public int data4 = 4;
private int data5 = 5;
public static final int data6 = 6;
public InnerClass() {
System.out.println("内部类构造方法!");
}
public void printInnerclass() {
System.out.println("内部类成员方法打印:"+data1+data2+data3+data4+data5);
System.out.println("内部类的data1:"+data1);
System.out.println("外部类的data1:"+OuterClass.this.data1);
}
}
public void printOuterclass() {
System.out.println("外部类成员方法打印:"+data1+data2+data3);
}
}
public class Test {
public static void main(String[] args) {
OuterClass outerClass = new OuterClass();
outerClass.printOuterclass();
OuterClass.InnerClass innerClass = outerClass.new InnerClass();
innerClass.printInnerclass();
}
}
注意事项:
- 外部类中的任何成员都可以被在实例内部类方法中直接访问
- 实例内部类所处的位置与外部类成员位置相同,因此也受public、private等访问限定符的约束
- 在实例内部类方法中访问同名的成员时,优先访问自己的,如果要访问外部类同名的成员,必须:外部类名称.this.同名成员来访问
- 实例内部类对象必须在先有外部类对象前提下才能创建
- 实例内部类的非静态方法中包含了一个指向外部类对象的引用
- 外部类中,不能直接访问实例内部类中的成员,如果要访问必须先要创建内部类的对象。
实例内部类
1、实例内部类当中 不能定义静态的成员变量?
~~~~ 如果定义 ~ 那么这个静态的成员应该是被final修饰的
2、实例内部类当中 ~ 不能定义静态的成员方法!!!
3、如何实例化 ~~ 实例内部类??
外部类类名.内部类 ~~~~ 变量 ~~~~ = ~~~~ 外部类引用.new ~~~~ 内部类();
OuterClass.InnerClass innerClass = outerClass.new InnerClass();
4、如何访问实例内部类 ~ 和 ~ 外部类的同名的成员变量??
~~~~~~ OuterClass.this
~~~~~~ 实例内部类当中 ~ 包含外部类的this
~~~~~~
5、如果是同名的静态的,OuterClass.data3
2、静态内部类
被 ~ static ~ 修饰的内部成员类称为静态内部类。
/**
* 静态内部类:
*
*/
class OuterClass {
public int data1 = 1;
private int data2 = 2;
private static int data3 = 3;
public void test() {
System.out.println(data1+data2+data3);
}
/**
* 1、如何拿到静态内部类的对象???
* OuterClass.InnerClass innerClass = new OuterClass.InnerClass();
*
* 2、不能在静态内部类当中,直接访问外部类非静态成员
*/
static class InnerClass {
public int data4 = 4;
private int data5 = 5;
private static int data6 = 6;
public InnerClass() {
System.out.println("静态内部类的构造方法!");
}
public void test() {
System.out.println("test方法执行了!!");
// 如何拿到外部类的非静态成员呢??
OuterClass outerClass = new OuterClass();
System.out.println(outerClass.data1);
System.out.println(outerClass.data2);
}
}
}
public class Test3 {
public static void main(String[] args) {
OuterClass.InnerClass innerClass = new OuterClass.InnerClass();
innerClass.test();
}
}
局部内部类
定义在外部类的方法体或者{}中,该种内部类只能在其定义的位置使用,一般使用的非常少,此处简单了解下语法
格式。
/**
* 局部内部类
*/
public class Test4 {
public static void func() {
class A {
public void test() {
System.out.println("局部内部类!!!");
}
}
A a = new A();
a.test();
}
public static void main(String[] args) {
func();
}
}
实际用的并不多,仅做了解即可
注意
- 局部内部类只能在所定义的方法体内部使用
- 不能被public、static等修饰符修饰
- 编译器也有自己独立的字节码文件,命名格式:外部类名字$内部类名字.class
- 几乎不会使用
匿名内部类
匿名对象的定义
匿名对象 只能使用一次 用完就销毁
Person类
public class Person {
String name;
int age;
public void test() {
System.out.println("阿漓");
}
}
Test类
public class Test {
public static void main(String[] args) {
new Person().test();//匿名对象 只能使用一次 用完就销毁
}
}
匿名内部类的定义
public class Test {
public static void main(String[] args) {
new Person() {
//匿名内部类: 在接口 与 多线程当中用的多
@Override
public void test() {
System.out.println("这是一个匿名内部类");
}
};
}
}
如何调用匿名内部类呢?
在最后.方法名即可
public class Test {
public static void main(String[] args) {
new Person() {
//匿名内部类: 在接口 与 多线程当中用的多
@Override
public void test() {
System.out.println("这是一个匿名内部类");
}
}.test();
}
}
- 如何拿到实例内部类的对象???
- OuterClass.InnerClass innerClass = outerClass.new InnerClass();
- 1、如何拿到静态内部类的对象???
- OuterClass.InnerClass innerClass = new OuterClass.InnerClass();
toString方法
@Override//注释:注释+解释【代表这个方法是重写父类的】
@Override//注释:注释+解释【代表这个方法是重写父类的】
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
'}';
}
实际上就是将所有的成员变量进行输出打印
测试效果:
因为这里我并没有初始化所以都是一些默认值
也可以写完toString方法以后再写
System.out.println(person);
看看效果
存储规则
局部变量和调用方法在栈上,而成员变量和 n e w 的对象在堆上 \color{red}{局部变量和调用方法在栈上,而成员变量和new的对象在堆上} 局部变量和调用方法在栈上,而成员变量和new的对象在堆上
2022年10月5日17:50:24