• JavaSE - 封装、static成员和内部类


    目录

    1. 封装

    1.1 什么是封装

    1.2 访问限定符(private、default、protected、public)

    2. 包

    2.1 导入Java提供的现成的包中的类

    2.2 自定义包

    2.3 常见的包

    3. static成员

    3.1 static修饰成员变量

    3.2 成员变量有无static的 赋值 对比

    3.2.1 给static修饰的静态成员变量进行赋值:

    3.2.2 给对象中的成员变量进行赋值:

    3.2.3 成员变量既有非静态的又有静态的​​​​​​​

    3.2 static修饰成员方法

    4. 代码块

    5. 内部类

    5.1 实例内部类

    5.2 静态内部类

    5.3 局部内部类

    6. 对象的打印


    1. 封装

    面向对象程序三大特性:封装、继承、多态。

    1.1 什么是封装

    对类内部的实现细节进行隐藏/封装,对外只提供一些公开的接口,供其他的用户进行访问

    Java中主要通过类和访问权限来实现封装:类可以将数据以及封装数据的方法结合在一起,而访问权限用来控制方法或者字段能否直接在类外使用

    1.2 访问限定符(private、default、protected、public)

    可以修饰成员变量,成员方法,构造方法


    private:私有的 ->只能在当前类的内部进行访问【同一个包中的同一个类

    default:默认的 ->只能在【同一个包中】进行访问【什么限定符都不加,就是default权限:默认权限】

    protected:受保护的【同一个包中和不同包中的子类

    public:公开的 ->不管在哪里都可以访问它

    一般情况下成员变量设置为private,成员方法设置为public。


    2. 包

    为了更好的管理类,把多个类收集在一起成为一组,称为包

    2.1 导入Java提供的现成的包中的类

    可以使用 import导入一个包中具体的类,使用import static导入包中静态的方法和字段。

    用到哪个类,就导入这个包中的这个类,如用到 java.util.Date这个类就导入 java.util 这个包中的 Date 类( java.util.Date->完整的类名、Date->不完整的类名,当没有和别的包下的类名产生冲突时,可以直接使用)

    如下:先进行实例化,再通过引用点号来访问类中的成员

    但是我们会发现,有些类中成员的访问不需要实例化,直接类名.方法名就可以,如下:

    这是为什么呢? 

    因为java.lang.Math和java.util.Arrays这两个类中提供了大量的静态方法,所以在使用的时候,直接【类名.方法名】使用即可。

    2.2 自定义包

    通过类外的 package 语句确定该类在哪个包中

    如果一个类外没有 package 语句, 则该类被放到一个默认包(src)中

    src里的类可以实例化src里的其他类 以及 src里的包中的类,而src里的包中的类却不能实例化src里的类。【即只能实例化同等级及以下的类。】

    详解private访问限定符

    2.3 常见的包

    1. java.lang:系统常用基础类(String、Object),此包不需要我们导入,编译器会自己导入

    2. java.lang.reflect:java 反射编程包

    3. java.net:进行网络编程开发包

    4. java.sql:进行数据库开发的支持包

    5. java.util:是java提供的工具程序包。(集合类等) 非常重要

    6. java.io:I/O编程开发包

    3. static成员

    1. 在Java中,被static修饰的成员,称之为静态成员,也可以称为类成员,其不属于某个具体的对象是所有对象所共享的。类变量存储在方法区当中,只有一份

    2. .通过【类名.属性/方法】去访问,若处于同一个类下,类名可以省略

    ( 虽然也可以通过引用来访问,语法上没错,但不要这样用)

    3. 静态成员变量未初始化默认是初始值。

    4. static修饰的是成员变量或成员方法,修饰方法中的局部变量

    5. 生命周期伴随类的一生【随着类的创建而产生,随着类的销毁而销毁】

    3.1 static修饰成员变量

    再谈学生类,若这些学生是同一个班的,就可以定义一个静态成员变量classes

    通过【类名.成员变量】进行访问

    那么如何给静态成员变量进行初始化呢?

    3.2 成员变量有无static的 赋值 对比

    3.2.1 给static修饰的静态成员变量进行赋值:

    1. 定义时就直接赋值

    2. 在main函数中通过【类名.成员变量】进行赋值

    3. 使用静态成员方法

    4. 使用静态代码块

    1. /**
    2. * 给static修饰的静态成员变量进行赋值
    3. * 1. 使用静态成员方法
    4. * 2. 通过静态代码块赋值
    5. */
    6. public class Peo {
    7. private static String name;
    8. private static int age;
    9. private static String sex = "男";//就地初始化
    10. private static String lover;
    11. /**
    12. * 1. 使用静态成员方法
    13. */
    14. public static void setPeople1(String name,int age){
    15. Peo.name = name;
    16. Peo.age = age;
    17. }
    18. /**
    19. * 2. 通过静态代码块赋值
    20. */
    21. static{
    22. lover = "骆闻舟";
    23. }
    24. public static void printPeople1() {
    25. System.out.println(Peo.name+" "+Peo.age +" "+Peo.sex+" 爱人:"+Peo.lover);
    26. }
    27. public static void main(String[] args) {
    28. Peo.setPeople1("费渡",22);
    29. Peo.printPeople1();
    30. }
    31. }

    3.2.2 给对象中的成员变量进行赋值:

    1. 定义时就直接赋值

    2. 在main函数中通过【引用.成员变量】进行赋值

    3. 使用成员方法

    4. 使用构造方法

    (有参数的构造方法、调用本类当中的其他构造方法)

    1. /**
    2. * 给对象中的成员变量进行赋值
    3. * 1. 使用成员方法(使用前一定会先调用无参构造方法)
    4. * 2. 使用构造方法
    5. * 3. 调用本类当中的其他构造方法
    6. *
    7. * 对比后发现,构造方法更好用
    8. */
    9. public class People {
    10. private String name;
    11. private int age;
    12. private String sex = "男";//就地初始化
    13. private String lover;
    14. /**
    15. * 1. 使用成员方法
    16. */
    17. public void setPeople1(String name,int age,String lover){
    18. this.name = name;
    19. this.age = age;
    20. this.lover = lover;
    21. }
    22. public void printPeople1() {
    23. System.out.println(this.age+"岁的"+this.name+"救赎了他的宝贝"+this.lover);
    24. }
    25. /**
    26. * 2. 使用构造方法
    27. */
    28. public People(String name,int age,String lover){
    29. this.name = name;
    30. this.age = age;
    31. this.lover = lover;
    32. }
    33. public void printPeople2(){
    34. System.out.println(this.age+"岁的"+this.name+"爱上了只属于他的"+this.lover);
    35. }
    36. /**
    37. * 3. 调用本类当中的其他构造方法进行初始化
    38. */
    39. public People(){
    40. this("陶然",29,"常宁");//this();调用本类中的其他构造方法
    41. }
    42. public void printPeople3(){
    43. System.out.println(this.age+"岁的"+this.name+"追上了它的女神"+this.lover);
    44. }
    45. public static void main(String[] args) {
    46. People people1 = new People();//调用无参构造方法
    47. people1.setPeople1("骆闻舟",29,"费渡");//重新初始化
    48. People people2 = new People("费渡",22,"骆闻舟");调用有2个参数的构造方法
    49. People people3 = new People();//调用无参构造方法
    50. people1.printPeople1();
    51. people2.printPeople2();
    52. people3.printPeople3();
    53. }
    54. }

    3.2.3 成员变量既有非静态的又有静态的

    1. public class Character {
    2. private String name;
    3. private String lover;
    4. private static String novel;
    5. static{
    6. novel = "默读";
    7. }
    8. public Character(String name,String lover){
    9. this.name = name;
    10. this.lover = lover;
    11. }
    12. public void printCharacter() {
    13. System.out.println(" "+Character.novel+":"+this.name+"和"+this.lover+"的相遇相知相爱,是梦开始的地方");
    14. }
    15. public static void main(String[] args) {
    16. Character character = new Character("费渡","骆闻舟");
    17. character.printCharacter();
    18. }
    19. }

    3.2 static修饰成员方法

    通过【类名.成员方法】访问

    在静态的成员方法内部,不能直接访问非静态的成员变量和成员方法。

    因为func是类名调用,不需要new对象,不需要对象的引用,this在静态方法中根本就不存在

    反之非静态可以访问静态。

    4. 代码块

    普通代码块、静态代码块、实例代码块(也叫构造块)、同步代码块。

    1. 使用static定义的代码块称为静态代码块。一般用于初始化静态成员变量

    2. 实例代码块,也叫作构造块,一般用于初始化非静态的成员变量。

    3. 静态代码块类加载的时候被执行了,它不依赖于对象,且只会执行一次

    4. 实例代码块无参数的构造方法只有在创建对象时才会执行,且创建几个对象执行几次

    5. 执行顺序:先静态代码块,再实例代码块,再无参数的构造方法

    6. 如果一个类中包含多个静态代码块,在编译代码时,编译器会按照定义的先后次序依次执行

    1. public class Stu {
    2. public String name;
    3. public int age;
    4. public String sex;
    5. public static String classes = "106Java1班";//静态成员变量
    6. {
    7. //实例代码块一般用于初始化非静态的成员变量。
    8. sex = "男";
    9. System.out.println("这是实例代码块!");
    10. }
    11. static{
    12. //静态代码块,一般用于初始化静态成员变量。
    13. classes = "106Java2班";//虽然classes已经被赋值成106Java1班,但要按顺序,最终输出106Java2班
    14. //类加载的时候 就被执行了,且只执行一次
    15. System.out.println("这是静态代码块!");
    16. }
    17. public Stu(){
    18. System.out.println("这是无参构造方法!");
    19. }
    20. public void setStu(String name,int age){
    21. this.name = name;
    22. this.age = age;
    23. }
    24. public void printStu(){
    25. System.out.println(this.name+" "+this.age+" "+sex+" "+Stu.classes);
    26. }
    27. public static void main(String[] args) {
    28. Stu stu = new Stu();
    29. stu.setStu("zhangsan",18);
    30. stu.printStu();
    31. Stu stu2 = new Stu();
    32. stu2.setStu("lisi",19);
    33. stu2.printStu();
    34. }
    35. }

    5. 内部类

    当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服 务,那么整个内部的完整结构最好使用内部类。内部类也是封装的一种体现。

    分类:

    1. 实例内部类(又叫构造内部类、非静态内部类)
    2. 静态内部类
    3. 局部内部类
    4. 匿名内部类

    5.1 实例内部类

    final - 定义常量

    1. package inner;
    2. class OuterClass {
    3. public int data1 = 1;
    4. int data2 = 2;
    5. public static int data3 = 3;
    6. public void test(){
    7. System.out.println("OuterClass:test()");
    8. InnerClass innerClass = new InnerClass();
    9. innerClass.func();
    10. }
    11. /**
    12. * 实例内部类
    13. * 1. 如何获取 实例内部类的对象
    14. * OuterClass.InnerClass innerClass = outerClass.new InnerClass();
    15. * 2.(1)实例内部类当中 不能有静态的成员变量,非要定义,那么就只能是被static final 修饰的
    16. * 因为静态成员变量在类(OuterClass)加载时就会被执行,
    17. * 而InnerClass实例化需要外部类对象的引用(outerClass),要先有外部类对象
    18. * 静态成员会先于InnerClass执行,所以静态的成员变量不能在实例内部类中
    19. * (2) 在static后加上final并且赋值了,就不报错可以运行了
    20. * 因为加上final再赋值,此代码就相当于一个常量,常量在编译时就确定了它的值
    21. * final是常量的意思
    22. * 3. 若外部类和实例内部类有相同的成员变量,那么输出遵循就近原则
    23. * 那在实例内部类当中,如何访问外部类当中,相同的成员变量呢?(类.this.成员变量)
    24. * 在实例内部类当中,获取外部类的this : OuterClass.this.data1
    25. *
    26. */
    27. class InnerClass{
    28. public int data1 = 111;
    29. public int data4 = 4;
    30. int data5 = 5;
    31. //public static int data6;//error
    32. public static final int data6 = 10;
    33. public void func(){
    34. System.out.println("InnerClass:func()");
    35. /*OuterClass outerClass = new OuterClass();
    36. System.out.println(outerClass.data1);*/
    37. System.out.println(data1);//111(就近原则)
    38. System.out.println(OuterClass.this.data1);//1//非要输出外部类中的成员变量可以这样
    39. System.out.println(data2);//2
    40. System.out.println(data3);//3
    41. System.out.println(data4);//4
    42. System.out.println(data5);//5
    43. System.out.println(data6);//10
    44. test();
    45. }
    46. }
    47. }
    48. public class Test {
    49. public static void main(String[] args) {
    50. OuterClass outerClass = new OuterClass();
    51. /* System.out.println(outerClass.data1);*/
    52. OuterClass.InnerClass innerClass = outerClass.new InnerClass();
    53. innerClass.func();
    54. OuterClass.InnerClass innerClass2 = new OuterClass().new InnerClass();
    55. }
    56. }

    1. 实例内部类方法中可以直接访问外部类中的任何成员

    2. 外部类中,不能直接访问实例内部类中的成员,如果要访问必须先要创建内部类的对象

    3. 实例内部类所处的位置与外部类成员位置相同,因此也受public、private等访问限定符的约束

    4. 在实例内部类方法中访问同名的成员时,优先访问自己的,如果非要访问外部类同名的成员,必须:【外部类名称.this.同名成员】来访问

    5. 实例内部类对象必须在先有外部类对象前提下才能创建

    5.2 静态内部类

    1. package inner;
    2. class OuterClass2 {
    3. public int data1 = 1;
    4. int data2 = 2;
    5. public static int data3 = 3;
    6. public void test(){
    7. System.out.println("OuterClass:test()");
    8. }
    9. /**
    10. * 静态内部类
    11. * 1. 如何获取 静态内部类的对象
    12. * OuterClass2.InnerClass2 innerClass2 = new OuterClass2.InnerClass2();
    13. * 2. 静态内部类当中,不能访问外部类的非静态成员,外部类的非静态成员,
    14. * 需要通过外部类的对象的引用才能访问
    15. * 非要访问: OuterClass2 outerClass2 = new OuterClass2();
    16. * System.out.println(outerClass2.data1);
    17. * System.out.println(outerClass2.data2);
    18. */
    19. static class InnerClass2{
    20. public int data4 = 4;
    21. int data5 = 5;
    22. public static int data6 = 6;
    23. public void func(){
    24. System.out.println("InnerClass:func()");
    25. OuterClass2 outerClass2 = new OuterClass2();
    26. System.out.println(outerClass2.data1);
    27. System.out.println(outerClass2.data2);
    28. /*System.out.println(data1);//error
    29. System.out.println(data2);//error*/
    30. System.out.println(data3);//3
    31. System.out.println(data4);//4
    32. System.out.println(data5);//5
    33. System.out.println(data6);//6
    34. }
    35. }
    36. }
    37. public class Test2 {
    38. OuterClass2.InnerClass2 innerClass2 = new OuterClass2.InnerClass2();
    39. }

    1.  在静态内部类中只能访问外部类中的静态成员

    2.  创建静态内部类对象时,不需要先创建外部类对象

    5.3 局部内部类

    定义在外部类的方法体中,只能在其定义的位置使用。几乎不被使用

    1. public class Test {
    2. public void func(){
    3. //局部内部类:
    4. class Inner{
    5. public void test(){
    6. System.out.println("hello");
    7. }
    8. }
    9. Inner inner = new Inner();
    10. inner.test();
    11. }
    12. }

    1. 局部内部类只能在所定义的方法体内部使用

    2. 不能被public、static等修饰符修饰

    6. 对象的打印

    重写toString方法

    1. public class Test {
    2. private String name = "zhangsan";
    3. private int age = 18;
    4. @Override
    5. public String toString() {
    6. return name + " " +age ;
    7. }
    8. public static void main(String[] args) {
    9. Test test = new Test();
    10. System.out.println(test);
    11. }
    12. }

  • 相关阅读:
    iOS——【Blocks】
    0 基础 Java 自学之路(5)
    智慧公厕改变城市生活,厕所革命标杆应用解决方案
    堆内存诊断
    网络爬虫 -- 验证码识别
    Java多线程基础知识-2
    北京/上海/广州/深圳DAMA-CDGA/CDGP数据治理认近期开班
    基于SpringBoot的企业客户管理系统
    4.6 - 堆 4.7 - 图
    687. 最长同值路径 ●●
  • 原文地址:https://blog.csdn.net/m0_61731585/article/details/126176156