• java的面向对象基础(1) —— 封装


    嵌入式之路,贵在日常点滴

                                                                    ---阿杰在线送代码

    目录

    面向对象有三大特征:

    一、封装的概念

    二、类的封装以及使用: 

    三、访问修饰符

    四、属性封装的实现

    五、方法封装的实现

    六、UML类图 

    七、类的构造方法与可重载

    八、this关键字

    九、static关键字

    static关键字的注意事项 

    十、方法重载:overload

    十一、包:package

    打包的意义:

    package —— 声明包

    怎样使用其他包中的公开类?

    实际地去做一个包


    面向对象有三大特征:

    1.封装
    2.继承
    3.多态

    封装 ,大白话的解释就是,把一个东西,装到箱子了,只留小小的口,用于外界访问 

    就是该露的露,该藏的藏 

    一、封装的概念

    字段和方法包装进类中,加上具体实现的隐藏(访问修饰符),共同被称作为封装,其结果是一个同时带有特征和行为的数据类型。

    定义类,定义其属性、方法的过程称为封装类。 

    学会从C语言的结构体中转换概念:

    1. struct Student
    2. {
    3. int age; //类似与java中的属性 特征
    4. char* name;
    5. void (*introduce)(int age,int name,int score); //函数 = 行为
    6. void (*testFunc)();
    7. };

    二、类的封装以及使用: 

    1. //封装一个类
    2. class Student //写规范来,第一个字母大写
    3. {
    4. int age; //属性
    5. String name;
    6. double score;
    7. void introduce(){ // 方法 = C语言中的函数
    8. System.out.println("my name is"+name + "age:"+age + "score"+score);
    9. } //面向对象的特性就是方法可以访问本类的特征属性,不需要额外的去传参
    10. void testFunc(){
    11. System.out.println("testFunc");
    12. }
    13. }
    14. //怎么使用这个类呢?
    15. public class Demo1 {
    16. public static void main(String[] args) {
    17. Student stu1 = new Student();
    18. //这操作叫实例化一个对象
    19. //类 = 模板,类不能直接使用,不能直接访问变量,需要先实例化,申请一个空间。
    20. //改成Student stu1 = null,好比C语言的指针使用前不malloc开辟空间
    21. /*这操作就等同于在c语言中,我们对结构体指针的定义及访问
    22. struct Student* p;
    23. p = malloc(sizeof(struct Student));
    24. */
    25. stu1.age = 18;
    26. stu1.score = 99.5;
    27. stu1.name = "ajie"; //不需要像C语言中strcpy赋值
    28. stu1.introduce();
    29. }
    30. }

    其中比较重要的概念:

    面向对象的特性就是方法可以访问本类的特征属性,不需要额外传参

    三、访问修饰符

    访问修饰符用于信息隐藏,是OOP(Object Oriented Programming面向对象的编程)最重要的功能之一。

    隐藏信息的原因:

    (1)对模块的任何实现细节所做的更改不会影响使用该模块的代码
    (2)防止用户意外修改数据
    (3)使模块易于维护和使用(就是电脑配件)
    (4)规范方法,特征的使用空间 

    访问修饰符:访问权限,可以看到private是最严格的: 

    位置private默认protectedpublic
    同一个类
    同一个包内的类
    不同包内的子类
    不同包且不是子类

    权限怎么理解呢?

    下面就以 “只有正确输入银行卡密码才能读取银行卡信息” 为例子

    四、属性封装的实现

    封装属性:修改属性的可见性来限制对属性的访问。

    为每个属性创建一对赋值方法(setter)和取值(getter)方法,用于公开对这些属性的访问接口,在getter和setter方法中,根据需要加入对属性操作的限制。

    举一个最简单的例子:

    1. class Student
    2. {
    3. private int sex;//可以通过下面的方法间接访问隐私属性
    4. public void setsex(int finalsex)
    5. {
    6. sex = finalsex;
    7. }
    8. public int getsex()
    9. {
    10. return sex;
    11. }
    12. }
    13. public class Demo2 {
    14. public static void main(String[] args) {
    15. Student stu1 = new Student();
    16. stu1.setsex(10);
    17. System.out.println("sex="+stu1.getsex());
    18. }
    19. }

    运行结果:

    sex=10 

    五、方法封装的实现

    先设置自己的真实年龄为36岁,当别人当面问你多少岁时,通过“封装的”不对外公开的方法修改了自己的真实年龄,再告诉他我18岁。

    但是如果直接访问简历上的年龄,通过这个方法访问到的就是真实年龄36岁

    1. class Age//注意这个类的名字第一个大写(好习惯),不能跟下面的age一样
    2. {
    3. private int age;
    4. void setAge(int realAge){
    5. age = realAge;
    6. }
    7. private void tellAlie(int falseAge)//“封装的”不对外公开的方法
    8. {
    9. age = falseAge;
    10. }
    11. void askMyAge()//当别人问我的姓名
    12. {
    13. tellAlie(18); //外部不知道这个方法的存在
    14. System.out.println("别人问我我就说我永远"+age);
    15. }
    16. void resumeAge()
    17. {
    18. System.out.println("简历上是真实年龄:"+age);
    19. }
    20. }
    21. public class Demo3 {
    22. public static void main(String[] args) {
    23. Age a1 = new Age();
    24. a1.setAge(36);
    25. a1.resumeAge();//通过这个方法访问到的是真实年龄
    26. a1.askMyAge(); //不对外公开的方法修改了真实年龄
    27. }
    28. }

    六、UML类图 

    UML-Unified Modeling Language 统一建模语言,又称标准建模语言。

    (1)类的命名尽量采用应用领域内的术语

    (2)类的属性、操作中的可见性用+ # -分别表示public protected private

    七、类的构造方法与可重载

    构造方法负责对象初始化工作,为对象的属性赋合适的初始值。

    在用户操作对象之前,系统就已经完成了类的构造方法。

    构造方法的语法规则

    (1)构造方法名与类名一致
    (2)没有返回类型
    (3)方法实现主要为特征赋初值

    构造方法的调用很特别:实例化对象(new)的时候,自动被调用

    java系统保证每个类都有构造方法:如果没有指明,系统将自动为其分配“空参数”的构造方法。

    1. class Student
    2. {
    3. private int age;
    4. int momAge;
    5. String name;
    6. float score;
    7. //方法名字与类名相同
    8. //构造方法在实例化对象new时会被调用,到时候再传递参数
    9. //如果不写,系统自动实现,无参无内容
    10. Student(int newAge,String newName,float newScore)
    11. {
    12. System.out.println("构造方法一被调用");
    13. age = newAge;
    14. name = newName;
    15. score = newScore;
    16. }
    17. //java中,方法是可重载的,即为函数名一样,参数列表不同即可
    18. Student(String newName)
    19. {
    20. System.out.println("构造方法二被调用");
    21. name = newName;
    22. }
    23. Student(String newName,float newScore)
    24. {
    25. System.out.println("构造方法三被调用");
    26. name = newName;
    27. score = newScore;
    28. }
    29. //传入参数类型不同,调换顺序就成为新的构造方法
    30. Student(float newScore,String newName)
    31. {
    32. System.out.println("构造方法四被调用");
    33. name = newName;
    34. score = newScore;
    35. }
    36. /* 不能同时有两个int int类似的构造方法,否则数据混淆,IDEA不给你用
    37. Student(int newAge,int newMomAge)
    38. {
    39. System.out.println("构造方法五被调用");
    40. age = newAge;
    41. momAge = newMomAge;
    42. }
    43. */
    44. }
    45. public class Demo1 {
    46. public static void main(String[] args) {
    47. //使用哪种构造方法,根据传入的参数而定(不仅是靠个数判断)
    48. Student stu1 = new Student(20,"ajie",100);
    49. Student stu2 = new Student("ajie");
    50. Student stu3 = new Student("ajie",100);
    51. Student stu4 = new Student(100,"ajie");
    52. //Student stu5 = new Student(100,100);
    53. System.out.println(stu1.name + stu1.score);
    54. }
    55. }

    运行结果: 

    构造方法一被调用
    构造方法二被调用
    构造方法三被调用
    构造方法四被调用
    ajie100.0 

    八、this关键字

    (3)(5)常用 

    (1)在类的方法中,使用this关键字代表的是调用此方法的对象的引用

    1. class student
    2. {
    3. String name;
    4. int age;
    5. void thisTest()
    6. {
    7. //第一种使用方法示例:
    8. System.out.println(this.name);
    9. }
    10. //第四种使用方法示例:构造方法中又调用另一个构造方法
    11. student(String name){
    12. System.out.println("构造方法2被调用了");
    13. this.name = name;
    14. }
    15. }
    16. public class Demo1 {
    17. public static void main(String[] args) {
    18. student stu1 = new student("ajie");//被指定了使用这个构造方法
    19. stu1.thisTest();//thisTest是一种方法,而stu1是调用这个方法的对象
    20. //this就是对这个对象的一种引用,引用他的特征,所以
    21. //会输出stu1对象的信息
    22. }
    23. }

    运行结果:

    构造方法2被调用了
    ajie

    (2)this可以看做是一个变量,它的值是对当前对象的引用

    (4)当在方法内需要用到该方法的对象时,就可以使用this 

    1. class student
    2. {
    3. String name;
    4. int age;
    5. void thisTest()
    6. {
    7. //第二种使用方法示例:
    8. student stuTemp = null;//临时的对象,太像结构体指针了
    9. stuTemp = this; //把当前对象赋给stuTemp.当前对象:如果是对象stu1,那么就是stu1对象赋给它
    10. System.out.println(stuTemp.name);//必须开辟空间(有对象)
    11. }
    12. //第四种使用方法示例:构造方法中又调用另一个构造方法
    13. student(String name){
    14. System.out.println("构造方法2被调用了");
    15. this.name = name;
    16. }
    17. }
    18. public class Demo1 {
    19. public static void main(String[] args) {
    20. student stu1 = new student("ajie");//被指定了使用这个构造方法
    21. stu1.thisTest();//thisTest是一种方法,而stu1是调用这个方法的对象
    22. //this就是对这个对象的一种引用,引用他的特征,所以
    23. //会输出stu1对象的信息
    24. }
    25. }

    运行结果:

    构造方法2被调用了
    ajie

    (3)可以处理方法中的成员变量与形参同名的问题

    1. class student
    2. {
    3. String name;
    4. int age;
    5. //第三种使用方法示例:最常用的解决同名问题
    6. /*student(String name,int age){
    7. name = name;
    8. age = age;
    9. } */
    10. student(String name,int age){
    11. System.out.println("构造方法1被调用了");
    12. this.name = name; //name传给当前对象的name
    13. this.age = age;
    14. }
    15. }
    16. public class Demo1 {
    17. public static void main(String[] args) {
    18. student stu1 = new student("ajie",18);//被指定了使用这个构造方法
    19. }
    20. }

    (5)在类的构造方法中可以调用this([参数列表])来调用该类的指定构造方法  

    1. class student
    2. {
    3. String name;
    4. int age;
    5. //第三种使用方法示例:最常用的解决同名问题
    6. /*student(String name,int age){
    7. name = name;
    8. age = age;
    9. } */
    10. student(String name,int age){
    11. System.out.println("构造方法1被调用了");
    12. this.name = name; //name传给当前对象的name
    13. this.age = age;
    14. }
    15. //第四种使用方法示例:构造方法中又调用另一个构造方法
    16. student(String name){
    17. this("ajie",21); //this构造方法只能放在第一句!!!
    18. System.out.println("构造方法2被调用了");
    19. this.name = name;
    20. }
    21. }
    22. public class Demo1 {
    23. public static void main(String[] args) {
    24. student stu1 = new student("ajie");
    25. }
    26. }

    运行结果:

    构造方法1被调用了
    构造方法2被调用了

    九、static关键字

    (1)用来修饰类的成员 —— 修饰成员变量的成为类变量(静态变量)

    1. class Student
    2. {
    3. int age;
    4. String name;
    5. double score;
    6. static int data;//(1)类变量(静态变量)
    7. Student(int age,String name,double score){ //构造方法
    8. System.out.println("构造方法");
    9. this.age = age;
    10. this.name = name;
    11. this.score = score;
    12. }
    13. void introduce(){
    14. System.out.println("名字:"+name + " 年龄:"+age + " 分数:"+score);
    15. }
    16. }
    17. public class Test {
    18. public static void main(String[] args) {
    19. Student stu1 = new Student(18,"ajie",99.5);//实例化
    20. //通过对象访问类的属性(成员),可以
    21. stu1.age = 10;
    22. //不实例化,通过类名访问类的属性(成员),会报错
    23. //Student.agt = 10;
    24. //(1)非要通过类名访问类的特征属性(成员),该成员变量就要定义为类变量(静态变量)
    25. Student.data = 10;
    26. }
    27. }

    (2)用来修饰成员方法 —— 称之为类方法(静态方法)

    1. public class Test {
    2. public static void main(String[] args) {
    3. //(2)
    4. System.out.println("ret = "+add(1,1));//不通过对象,直接访问类的方法
    5. }
    6. //(2)脱离对象,直接使用方法
    7. static int add(int a,int b){ //脱离对象,直接使用方法
    8. return a + b;
    9. }
    10. }

     (3)当类被加载的时候就会被加载,优先于对象的存在

    (4)用来修饰语句块 —— 称之为静态代码块,先于构造方法之前执行,只会执行一次,用来对静态成员做初始化。

    1. class Student
    2. {
    3. int age;
    4. String name;
    5. double score;
    6. static int data;//(1)类变量(静态变量)
    7. Student(int age,String name,double score){ //构造方法
    8. System.out.println("构造方法");
    9. this.age = age;
    10. this.name = name;
    11. this.score = score;
    12. }
    13. static { //(4)静态代码块的格式要求
    14. System.out.println("静态代码块"); //静态代码块优先于构造方法执行
    15. data = 5; //并且只执行一次,因为静态变量同类一起,一开始就存在了(相对于需要创建的对象)
    16. } //但构造方法每次在实例化一个对象都会执行
    17. //static void test(){
    18. // System.out.println(this.age);//会报错 静态方法中不能出现this关键字
    19. // System.out.println(age);//会报错 静态方法中只能访问外部的静态成员 比如data
    20. //}
    21. void introduce(){
    22. System.out.println("名字:"+name + " 年龄:"+age + " 分数:"+score);
    23. }
    24. }
    25. public class Test {
    26. public static void main(String[] args) {
    27. Student stu1 = new Student(18,"ajie",99.5);//实例化
    28. Student stu2 = new Student(18,"ajie",99.5);//验证静态代码块只执行一次
    29. }
    30. }

    运行结果:

    静态代码块--静态代码块只执行一次    
    构造方法
    构造方法 

    (5)调用的时候可以直接通过类名.成员来进行访问。

    static关键字的注意事项 

    静态方法中只能访问外部的静态成员

    静态方法中不能出现this关键字 :this指的是对象的引用,而static是先于对象存在的

    1. class Student
    2. {
    3. int age;
    4. String name;
    5. double score;
    6. static int data;//(1)类变量(静态变量)
    7. static void test(){
    8. System.out.println(this.age);//会报错 静态方法中不能出现this关键字
    9. System.out.println(age);//会报错 静态方法中只能访问外部的静态成员 比如data
    10. }
    11. void introduce(){
    12. System.out.println("名字:"+name + " 年龄:"+age + " 分数:"+score);
    13. }
    14. }

    十、方法重载:overload

    同一个类中,同名不同参的方法成为重载方法(在上文类的构造方法与可重载中有大量的例子。)

    多数程序设计语言要求为每个方法(函数)提供一个独一无二的方法名,不存在方法重载的概念。而在java中,规定方法签名是解析方法的规则而不是方法名,为方法重载开创了条件。 

    方法重载使得在一个类中,方法名相同而参数列表不同的方法可同时存在,代表相似的行为或功能。

    注意:仅有返回值不同的方法不能成为重载

    System.out.print下面有很多的构造方法,也就是方法的重载 

    在这里插入图片描述

    十一、包:package

    标准java库是由一系列包组成,包括java.lang ,java.util,java.net等等。

    标准java包就是层次型包结构,就如同硬盘上嵌套的子目录一样,我们可以使用嵌套层次结构来组织包。

    打包的意义:

    java的包是为了更好地规划代码,防止命名冲突和混乱。所以java出现了打包机制。

    当把类组织起来放进一个包内时,也就给包中的成员赋予了相互访问的权限

    包访问权限把类聚集在一个包中这一做法提供了意义和理由

    package —— 声明包

    java程序员都可以编写属于自己的java包,为了保证包名唯一性,要求程序员在自己定义包的名字前加上唯一前缀。

    由于互联网上的域名名称不会重复,所以推荐采用公司在互联网上的域名的倒置作为包的唯一前缀,如 com.iotek.ch09 

    一个类可以使用同一个包中的所有类
    一个类可以使用其他包中的所有公开类 

    怎样使用其他包中的公开类?

    ①在每个类的签名之前加上完整包名,例如:

    java.util.Data today = new java.util.Date();
    

    ②更简洁更通用的方式:使用import语句来导包 (eclipse ctrl+shift+o

    import java.util.Date
    

    实际地去做一个包

    一个类可以使用同一个包中的所有类

    一个类可以使用其他包中的所有公开类 

  • 相关阅读:
    英语六级-day10
    Go语言sync.Map
    c语言:十进制转任意进制
    Delphi 开发so库,Delphi 调用SO库
    代码随想录算法训练营第四十五天 | 动态规划 part 7 | 70. 爬楼梯 (进阶)、322. 零钱兑换、279.完全平方数
    基于Python的决策树判断是否降雪
    【计算机网络】 传输层
    态势丨黑客侵扰加剧,靶场为网络安全架设“防御盾”
    每日一题47-48
    中科柏诚与知名上市公司南天信息(000948)签署战略合作协议
  • 原文地址:https://blog.csdn.net/weixin_50546241/article/details/126588143