Java面向对象详解(一)

一. 面向对象基础

  1. 面向对象思想

    1.1 概述

      面向对象是相对于面向过程来讲的,指的是把相关的数据和方法组织为一个整体来看待,从更高的层次来进行系统建模,更贴近事物的自然运行模式。

      面向过程到面向对象,是程序员思想上 从执行者到指挥者的转变。

    1.2  三大思想

      面向对象思想从概念上讲分为以下三种:OOA、OOD、OOP

      OOA:面向对象分析(Object Oriented Analysis)

      OOD:面向对象设计(Object Oriented Design)

      OOP:面向对象程序(Object Oriented Programming)

    1.3  三大特征

      封装性:所有的内容对外部不可见

      继承性:将其他的功能继承下来继续发展

      多态性:方法的重载本身就是一个多态性的体现

  2. 类和对象

   类表示一个共性的产物,是一个综合的特征,而对象,是一个个性的产物,是一个个体的特征。

    类必须通过对象才可以使用,对象的所有操作都在类中定义。

    类由属性和方法组成:

      属性:就相当于人的一个个的特征

      方法:就相当于人的一个个的行为,例如:说话、吃饭、唱歌、睡觉

  3. 创建对象内存分析

    3.1  栈

      Java栈的区域很小,大概2m左右,特点是存取的速度特别快

      栈存储的特点是,先进后出

      存储速度快的原因:

        (1)栈内存, 通过 '栈指针' 来创建空间与释放空间 

        (2)指针向下移动, 会创建新的内存,向上移动,会释放这些内存 

        (3)这种方式速度特别快,仅次于PC寄存器

        但是这种移动的方式, 必须要明确移动的大小与范围,明确大小与范围是为了方便指针的移动 , 这是一个对于数据存储的限制,存储的数据大小是固定的,影响了程序的灵活性。所以我们把更大部分的数据 存储到了堆内存中。

        存储的是基本数据类型的数据 以及 引用数据类型的引用。

    3.2 堆

      堆存放的是类的对象。Java是一个纯面向对象语言, 限制了对象的创建方式。new关键字,是指告诉JVM ,需要明确的去创建一个新的对象,去开辟一块新的堆内存空间。     

      堆内存与栈内存不同, 优点在于我们创建对象时,不必关注堆内存中需要开辟多少存储空间,也不需要关注内存占用时长,堆内存中内存的释放是由GC(垃圾回收器)完成的。当栈内存中不存在此对象的引用时,则视其为垃圾,等待垃圾回收器回收。

    3.3 方法区

      方法区存放的是:

        (1)类信息

        (2)静态的变量

        (3)常量

        (4)成员方法

    3.4 PC寄存器

      PC寄存器保存的是当前正在执行的JVM指令的地址,在Java程序中,每个线程启动时,都会创建一个PC寄存器。

    3.5 本地方法栈

      保存本地(native)方法的地址

  4. 构造方法

    4.1 概述

      用于对象初始化,在创建对象时自动调用。所有的Java类中都会至少存在一个构造方法,如果一个类中没有明确的编写构造方法,则编译器会自动生成一个无参的构造方法,构造方法中没有任何的代码。如果自行编写了任意一个构造器, 则编译器不会再自动生成无参的构造方法。

    4.2 格式

      例子:

        class Person{

          String name;

          int age;

          // 无参构造方法

          public Person(){

            System.out.println("对象创建时,此方法调用");

          }

          // 全参构造方法

          public Person(String name,int age){

            this.name = name;

            this.age = age;

          }

        }

    4.3 建议

      (1)建议自定义无参构造方法,不要对编译器形成依赖,避免错误发生。

      (2)当类中有非常量成员变量时,建议提供两个版本的构造方法,一个是无参构造方法,一个是全属性做参数的构造方法。

      (3)当类中所有成员变量都是常量或者没有成员变量时,建议不提供任何版本的构造。

  5.方法重载

    方法名称相同, 参数类型或参数长度不同(参数顺序), 可以完成方法的重载。

    方法的重载与返回值无关。

    方法的重载 ,可以让我们在不同的需求下, 通过传递不同的参数调用方法来完成具体的功能。

    例子:

        class Math{

 

        int sum (int x,int y){

          int z = x+y;

          return z;

        }

        // 参数类型不同

        double sum (double x,double y){

          double z = x+y;

          return z;

        }

        // 方法3和方法4的参数顺序不同,也可构成重载

        double sum (double x,int y){

          double z = x+y;

          return z;

        }

        double sum (int y,double x){

          double z = x+y;

          return z;

        }

        // 参数长度不同

        double sum (double x){

          double z = x+10;

          return z;

        }

       }

  6. 构造方法重载

    与方法重载类似

    空的构造方法和全参的构造方法其实就属于构造方法的重载

  7. 匿名对象

    没有对象名称的对象 就是匿名对象。

    匿名对象只能使用一次,因为没有任何的对象引用,所以将称为垃圾,等待被GC回收。  

    例子:

      public class Demo{

        public static void main (String[] args){

          int n = new Math().sum(100,200);

          System.out.println(n);

        }

      }

      class Math{

        int sum(int x,int y){

          return x+y;

        }

      }

    如果一个对象要使用两次或两次以上时必须要给对象创建对象名

    例子:  

      public class Demo{

        public static void main (String[] args){

          new Student().name = "张三";

          new Student().name = 18;

          new Student().say();

        }

      }

      class Student{

        String name;

        int age;

        void say(){

          System.out.println("姓名:"+name+"\n年龄:"+age);

        }

      }

      此时输出的结果为

      姓名:null

      年龄:0

      new三次对象相当于在堆中开辟三块空间

      第一块给只name赋值;第二块只给age赋值;第三块只调用say方法,此时没有赋值,因此name为null、age为0

 二. 面向对象进阶

  1. 封装private

    封装的意义在于保护或防止代码(数据)被我们无意中破坏。保护成员属性,不让类以外的程序直接访问和修改。

    原则:隐藏对象的属性和实现细节,仅对外公开访问方法,并且控制访问级别。

    在开发中,为了避免出现逻辑错误,我们建议对所有属性进行封装,并为其提供setter及getter方法进行设置和取得操作。

    例子:

      class Student{

        private String name;

        private int age;

        public void getName(){

          return this.name;

        }

        public void setName(String name){

          this.name = name;

        }

        public void getAge(){

          return this.age;

        }

        public void setAge(int age){

          this.age = age;

        }

      }

  2. this

    在Java基础中,this关键字是一个最重要的概念。使用this关键字可以完成以下的操作:

      (1)调用类中的属性

      (2)调用类中的方法或构造方法;在一个构造方法中,调用另一个构造方法时,调用的代码必须编写在构造方法的第一行。

        例子:

          Student(){

            this("默认姓名",1);

            System.out.println("123");

          }

          此时 this("默认姓名",1);必须写在第一行,因为在执行这句代码时对象还没初始化完毕,这时候如果执行其他代码时可能会

        造成某些错误,因此规则上必须写在第一行

          Student(String name,int age){

            this.name = name;

            this.age = age;

          }

      (3)表示当前对象

  3. static

    3.1 概述

      static表示“静态”的意思,可以用来修饰成员变量和成员方法

      static的主要作用在于创建独立于具体对象的域变量或者方法,可以简单理解为,被static关键字修饰的方法或者变量不需要依赖于

    对象来进行访问,只要类被加载了,就可以通过类名去进行访问。并且不会因为对象的多次创建 而在内存中建立多份数据。

    3.2 重点

      (1)静态成员在类加载时加载并初始化。

      (2)无论一个类存在多少个对象,静态的属性,永远在内存中只有一份( 可以理解为所有对象公用 )

      (3)在访问时: 静态不能访问非静态 , 非静态可以访问静态。静态修饰的方法被调用时,对象可能还没创建

        例子:

        (1)class Student{

          void static say(){

            System.out.println("你好");

          }

          void say2(){

            say();

          }

        }

        (2)class Student{

          void static say(){

            say2();

          }

          void say2(){

            System.out.println("你好");

          }

        }

        (1)不会报错,因为此时如果say2能执行,说名对象已经创建,则say一定存在。

        (2)会报错,因为say被调用时对象不一定创建,因此无法调用say2方法。

  4. 包

    4.1 包介绍

      (1)把功能相似或相关的类或接口组织在同一个包中,方便类的查找和使用。

      (2)包如同文件夹一样,不同的包中的类的名字是可以相同的,当同时调用两个不同包中相同类名的类时,应该加上包名加以区别。因此,包可以避免名字冲突。

      (3)包也限定了访问权限,拥有包访问权限的类才能访问某个包中的类。

    4.2 包的使用规则

      包的定义:

       通常由多个单词组成, 所有单词的字母小写, 单词与单词之间使用.隔开 ,一般命名为“com.公司名.项目名.模块名....”。 

    4.3 import关键字

      import 包名.类名

  5. 代码块

    (1)普通代码块

      在执行的流程中出现的代码块,我们称其为普通代码块。

    (2)构造代码块

      在类中的成员代码块,我们称其为构造代码块,在每次对象创建时执行,执行在构造方法之前。

      例子:

        {

          执行语句;

        }

    (3)静态代码块

      在类中使用static修饰的成员代码块,我们称其为静态代码块,在类加载时执行。每次程序启动到关闭只会执行一次的代码块。

        static{

          执行语句;

        }

    (4)同步代码块

      在后续多线程技术中学习。

    面试题:

      构造方法 与 构造代码块 以及 静态代码块的执行顺序:

        静态代码块 --> 构造代码块 --> 构造方法

      原因:静态代码块在对象还没创建时就已经执行,而构造代码块在构造方法执行前先执行,因此执行的顺序为 静态代码块 --> 构造代码块 --> 构造方法。

  6. 权限修饰符 

    修饰符        类        包        子类       其他包
    public          √         √     √      √
    protected    √    √     √            x
    default   √    √     x            x
    private        √          x          x            x

  7. main方法详解

    main()方法一直写到了今天:

    public static void main(String args[])

      以上的各个参数的含义如下:

        (1)public:表示公共的内容,可以被所有操作所调用

        (2)static:表示方法是静态的,可以由类名称直接调用。

        (3)void:表示没有任何的返回值操作

        (4)main:系统规定好的方法名称。如果main写错了或没有,会报错:NoSuchMethodError: main

        (5)String[] args:字符串数组,接收参数的

posted @   Luo_YB  阅读(102)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示