zoukankan      html  css  js  c++  java
  • Java对象和类

    java作为一种面向对象的语言,是支持多态,继承,封装,抽象,类,对象,实例,方法,重载.

    该文章研究对象和类的概念.

    • 对象:对象是类的一个实例(对象不是找个女朋友),有状态和行为。例如,一个人是一个对象,它的状态有:肤色、名字、性别;行为有:睡觉,、说话,吃等。
    • :类是一个模板,它描述一类对象的行为和状态。

    下图中男孩女孩为类,而具体的每个人为该类的对象:

    java中的对象

    什么是对象(object):万物皆对象:对象就是个体

    通过上图可以认为人就是对象,像生活中车,动物,植物等,这些都可以认为是对象,而且这些对象都有自己的状态和行为

    用车举例,它的状态有,品牌,颜色,行为有,启动,要玻璃窗等

    对比现实对象和软件对象,它们之间十分相似。

    软件对象也有状态和行为。软件对象的状态就是属性,行为通过方法体现。

    在软件开发中,方法操作对象内部状态的改变,对象的相互调用也是通过方法来完成。

    Java中的类

    类是对象的图纸,模板,

    通过下面一个简单的类来理解下Java中类的定义:

    public class people{
      String breed;
      int age;
      String color;
      void eating(){
      }
     
      void hungry(){
      }
     
      void sleeping(){
      }
    }

    一个类可以包含以下类型变量:

    • 局部变量:在方法、构造方法或者语句块中定义的变量被称为局部变量。变量声明和初始化都是在方法中,方法结束后,变量就会自动销毁。
    • 成员变量:成员变量是定义在类中,方法体之外的变量。这种变量在创建对象的时候实例化。成员变量可以被类中方法、构造方法和特定类的语句块访问。
    • 类变量:类变量也声明在类中,方法体之外,但必须声明为static类型。

    一个类可以拥有多个方法,在上面的例子中:eating()、hungry()和sleeping()都是People类的方法。

    类和对象之间的关系

    类是对象的图纸,模板.对象是类的实例化

    重点在于如何构建这个蓝图,模板

    如何去定义一个类,确定类和类之间的关系,下面介绍构造方法

     构造方法

    每个类都有构造方法。如果没有显式地为类定义构造方法,Java编译器将会为该类提供一个默认构造方法。

    在创建一个对象的时候,至少要调用一个构造方法。构造方法的名称必须与类同名,一个类可以有多个构造方法。

    对象新建的过程:Person p = new Person

    从广义的角度,构造器的作用:初始化:对对象使用之前进行信息的预处理

    构造器的定义:

    ①构造方法的方法名必须与类名保持一致

    ②构造方法没有返回值类型;构造方法返回的一定对象本体的内存地址

    ③构造方法仅仅允许使用访问权限修饰符进行修饰

    ④系统给每一个类都提供一个默认的空构造(没有参数的构造方法),这个构造方法仅仅用来给各个属性赋默认值

    ⑤默认的控构造只能在没有任何手动定义的构造器的类中使用:如果手动定义了一个构造方法,默认的构造方法就失效

    ⑥在同一个类中,可以存在多个构造器(构造器的重载)

    方法的重载

    java中如何区分两个方法

    ①方法的调用者:方法的调用者一旦确定,就能够根据调用者找到这个方法的归属

    ②方法名

    ③方法的形参列表

    ****注意:方法的返回值并不能用来区分两个方法:一个方法在调用的时候,可以接收返回值也可以不接收,在不接收返回值的时候,就没有办法通过返回值(类型)区分两个同名、相同形参列表、定义在同一个类中的方法

    方法的重载定义:两同一不同:在同一个类中,定义多个同名方法,使用不相同的形参列表进行区分

    不同的形参列表

      ①形参列表的长度(形参的个数)

      ②形参的类型

      ③形参的顺序

    注意:

    • 重载方法参数必须不同:

                   参数个数不同,如method(int x)与method(int x,int y)不同

                  参数类型不同,如method(int x)与method(double x)不同g

                  参数顺序不同,如method(int x,double y)与method(double x,int y)不同

    •  重载只与方法名与参数类型相关与返回值无关

                  如void method(int x)与int method(int y)不是方法重载,不能同时存在

    • 重载与具体的变量标识符无关

                  如method(int x)与method(int y)不是方法重载,不能同时存在

    区分方法

    创建对象

    对象是根据类创建的。在Java中,使用关键字new来创建一个新的对象。创建对象需要以下三步:

    • 声明:声明一个对象,包括对象名称和对象类型。
    • 实例化:使用关键字new来创建一个对象。
    • 初始化:使用new创建对象时,会调用构造方法初始化对象。

    下面是一个创建对象的例子

    public class People{
       public People(String name){
          //这个构造器仅有一个参数:name
          System.out.println("人的名字是 : " + name ); 
       }
       public static void main(String []args){
          // 下面的语句将创建一个People对象
          Puppy p= new People( "tom" );
       }
    }

    编译并运行上面的程序,会打印出下面的结果:

    人的名字是 : tom

    访问实例变量和方法

    通过已创建的对象来访问成员变量和成员方法,如下所示:

    /* 实例化对象 */
    ObjectReference = new Constructor();
    /* 访问类中的变量 */
    ObjectReference.variableName;
    /* 访问类中的方法 */
    ObjectReference.methodName();

    实例

    下面的例子展示如何访问实例变量和调用成员方法:

    public class People{
       int peopleAge ;
       public People(String name){
          // 这个构造器仅有一个参数:name
          System.out.println("人的名字是 : " + name ); 
       }
     
       public void setAge( int age ){
           peopleAge = age;
       }
     
       public int getAge( ){
           System.out.println("人的年龄为 : " + peopleAge ); 
           return peopleAge ;
       }
     
       public static void main(String []args){
          /* 创建对象 */
          People myPuppy = new People( "tom" );
          /* 通过方法来设定age */
          myPeople.setAge( 2 );
          /* 调用另一个方法获取age */
          myPeople.getAge( );
          /*你也可以像下面这样访问成员变量 */
          System.out.println("变量值 : " + myPeople.peopleAge ); 
       }
    }

    结果:

    人的名字是 : tommy
    人的年龄为 : 2
    变量值 : 2

    源文件声明规则

    在本节的最后部分,我们将学习源文件的声明规则。当在一个源文件中定义多个类,并且还有import语句和package语句时,要特别注意这些规则。

    • 一个源文件中只能有一个public类
    • 一个源文件可以有多个非public类
    • 源文件的名称应该和public类的类名保持一致。例如:源文件中public类的类名是Employee,那么源文件应该命名为Employee.java。
    • 如果一个类定义在某个包中,那么package语句应该在源文件的首行。
    • 如果源文件包含import语句,那么应该放在package语句和类定义之间。如果没有package语句,那么import语句应该在源文件中最前面。
    • import语句和package语句对源文件中定义的所有类都有效。在同一源文件中,不能给不同的类不同的包声明。

    类有若干种访问级别,并且类也分不同的类型:抽象类和final类等。这些将在访问控制章节介绍。

    除了上面提到的几种类型,Java还有一些特殊的类,如:内部类、匿名类。

    Java包

    包主要用来对类和接口进行分类。当开发Java程序时,可能编写成百上千的类,因此很有必要对类和接口进行分类。

    Import语句

    在Java中,如果给出一个完整的限定名,包括包名、类名,那么Java编译器就可以很容易地定位到源代码或者类。Import语句就是用来提供一个合理的路径,使得编译器可以找到某个类。

    例如,下面的命令行将会命令编译器载入java_installation/java/io路径下的所有类

    import java.io.*;

    一个简单的例子

    在该例子中,我们创建两个类:Employee 和 EmployeeTest

    首先打开文本编辑器,把下面的代码粘贴进去。注意将文件保存为 Employee.java。

    Employee类有四个成员变量:name、age、designation和salary。该类显式声明了一个构造方法,该方法只有一个参数。

    Employee.java 文件代码:

    import java.io.*;
     
    public class Employee{
       String name;
       int age;
       String designation;
       double salary;
       // Employee 类的构造器
       public Employee(String name){
          this.name = name;
       }
       // 设置age的值
       public void empAge(int empAge){
          age =  empAge;
       }
       /* 设置designation的值*/
       public void empDesignation(String empDesig){
          designation = empDesig;
       }
       /* 设置salary的值*/
       public void empSalary(double empSalary){
          salary = empSalary;
       }
       /* 打印信息 */
       public void printEmployee(){
          System.out.println("名字:"+ name );
          System.out.println("年龄:" + age );
          System.out.println("职位:" + designation );
          System.out.println("薪水:" + salary);
       }
    }

    程序都是从main方法开始执行。为了能运行这个程序,必须包含main方法并且创建一个实例对象。

    下面给出EmployeeTest类,该类实例化2个 Employee 类的实例,并调用方法设置变量的值。

    将下面的代码保存在 EmployeeTest.java文件中。

    EmployeeTest.java 文件代码:

    import java.io.*;
    public class EmployeeTest{
     
       public static void main(String []args){
          /* 使用构造器创建两个对象 */
          Employee empOne = new Employee("RUNOOB1");
          Employee empTwo = new Employee("RUNOOB2");
     
          // 调用这两个对象的成员方法
          empOne.empAge(26);
          empOne.empDesignation("初级程序员");
          empOne.empSalary(1000);
          empOne.printEmployee();
     
          empTwo.empAge(21);
          empTwo.empDesignation("小白程序员");
          empTwo.empSalary(500);
          empTwo.printEmployee();
       }
    }

    结果:

    自己可以敲一下键盘就知道了.........

    对象在内存中的存在形式

    Java vm内存:堆内存,栈内存

    栈内存:随时开辟,使用,回收-->Java中的方法在运行起来的时候

    会分配一个专有的占内存,方法运行结束,栈内存回收

    堆内存:长久存在,用来存储对象的本体的一个空间--》一个公共的内存空间

    Person p = new Person();

    P:对象引用,引用变量,对象名-》存在方法栈内存中

    new Persoon();对象本体--> 堆内存

    对象本体的空间开辟,赋值等过程是相对比较消耗时间和空间的,没哟个对象本体,都是宝贵的资源,能够重用就重用,对象本体不应该被随便的回收,应该将对象本体放在一个稳定的空间内,所以将对象本体放在堆内存 中

    凡是以对象本体和饮用方式存在的变量,都是引用数据类型的:数组,类的对象

    *****基本数据类型的变量都存储在栈内存中,和对象本体不一样

    栈:存储局部变量;堆:存储new出来的数组或对象

    对象的回收

    当一个对象本体失去所有的引用的时候,这个对象本体就变成一个弱引用对象

    JVM中提供一种机制——垃圾回收机制,垃圾回收器Garbage Collector

    垃圾回收机制会定期扫描内存空间,找到所有的弱引用对象,对其回收

    类的构成

    类的构成:变量和方法

    1.变量:

        按照位置进行划分:

            全局变量:(属性)

                按照静态进行划分

                    静态全局变量(类属性)

                    非静态全局变量 (对象属性)

            局部变量:

                定义在方法中的局部变量

                定义在代码块中的局部变量

                定义在方法参数列表中的形参(形式参数)

     

    局部变量

    局部变量的生命周期:

    想要访问一个局部变量,必须在这个局部变量的生命周期之内对其进行访问,在生命周期之外,要么这个变量尚未开始,要么这个变量的生命周期已经结束

    形参(形式参数):

    形参的生命周期贯穿整个方法

    形参的传递机制:值传递:值的拷贝

    对于基本数据类型:拷贝的是基本数据类型中的常量值,形参进行值得改变不会对实参的值发生影响

    对于引用数据类型:拷贝的是引用变量中存储的对象本体的地址,实参将地址拷贝给形参,实参和形参实际上指向的对象本体其实是同一个,其中一个对这个地址所在的对象本体进行修改,大家都能看得见

    全局变量:属性(Filed)

    生命在类之中、方法之外的变量

    全局变量的生命周期:在整个类中有效

    属性:相关信息的描述,通过众多的属性的有机结合,就能够描述一个特定的群体

    静态全局变量和非静态全局变量:

    静态全局变量(类属性):

    ①类属性都是用static进行修饰

    ②作用:用来描述一个类的对象都具有而且值相同的属性

    ③类属性的值是全部对象共享的,如果有一个对象对类属性进行修改,其他对象的这个类型属性的值也会发生变化

    ④类属性尽量通过静态的方式进行访问——通过类名的方式进行访问:类属性既可以通过类名访问也可以通过对象名访问

    ⑤类属性的作用

      1。可以用来记录一个类的属性信息

      2.记录程序在运行过程当中产生的中间值

      3.在类与类之间传递信息

    非静态全局变量(对象属性)

    ①对象属性都不用static修饰

    ②对象属性的作用;用来描述一个类的对象都具有,但是值个性化的属性

    ③对象属性的值是对象独享的,一个对象的对象属性发生改变,其他不会跟着发生改变 

    ④对象属性只能够通过非静态的方式进行访问:对象属性只能被对象名访问,类名不能够访问对象属性

    其他:

    类先定义在使用:用来new对象

    Java中的命名法:驼峰命名

    定义类、属性、方法:

    ①命名尽量使用英语单词

    ②明明使用的单词词组能够描述这个类、属性、方法的作用

    ③包名尽量完全使用小写字母:字母、数字、下划线  类名:如果一个类名由多个单词组成,各个单词的首字母大写,如果出现缩写,整个缩写单词都大写:TestMyMD5  变量名和方法名:第一个单词的首字母小写,之后其他单词的首字母大写

    add()  addElement() eye eyeNumber  属性的命名不允许使用数字作为开头

    空对象:null

    ①null并不依赖于任何一个类,null不是任何类的对象,没有任何一个类与null相对应

    ②但是任何一个类对象的引用变量都可以引用null String str = null;  Person p1 = null;  Car c1 = null;

    ③null或者指向null的引用变量不能够调用任何属性和方法,否则会引起NullPointerException

    2.方法:

    方法:

        按照功能进行区分:

            main方法:

            一般方法:

                按照静态与非静态:

                    静态方法:

                    非静态方法:    

            构造方法

    定义:一系列相关处理过程的集合

    方法的原子性:功能的模块化:在定义方法的时候,尽量将功能差分成不可再细分的子功能,大功能的完成取决于子功能呢的调用和配合

    方法的内聚性和耦合性:高内聚,低耦合

    内聚性:方法自行完成任务,尽量不依赖于外界条件的性质

    耦合性:方法完成一项任务需要依赖多少的外界条件

    方法:

        按照功能进行区分:

            main方法:

            一般方法:

                按照静态与非静态:

                    静态方法:

                    非静态方法:    

            构造方法:

     

    main方法:

    Main方法是所有程序的入口,程序运行起来首先执行main方法,在通过main方法中对其他方法的调用,达到运行程序的目的,

    形参String[] args:外部程序命令集

    在一般情况下,args != null,args.length == 0

    一般方法

    方法定义的一般语法

    Pubilc static void main(String[] args){}

    [访问权限修饰符][静态修饰符][final修饰符][同步修饰符]...返回值类型 方法名(形参列表)[声明异常抛出]

    静态方法:类方法

    ①使用static关键字进行修饰

    ②静态方法的作用:静态方法一般都是充当工具方法的作用,使用者仅关心这个方法的执行过程和执行结果,没必要关心是谁提供的这个方法

    ④静态方法(类方法)调用属性:类方法只能够调用类属性,不能够调用对象属性

    非静态方法:对象方法

    ①对象方法不使用static修饰

    ②对象方法仅能够通过对象调用:对象方法的调用结果取决于调用者

    ③对象方法的作用:因为调用者不同能够引起运行结果的不同,这样的方法应该声明成对象方法

    ④对象方法访问属性:对象方法即可以访问类属性也可以访问对象属性

     

     参数传递

    参数传递,可以理解当我们要调用一个方法时,我们会把指定的数值,传递给方法中的参数,这样方法中的参数就拥有了这个指定的值,可以使用该值,在方法中运算了。这种传递方式,我们称为参数传递。

    • l  在这里,定义方法时,参数列表中的变量,我们称为形式参数
    • l  调用方法时,传入给方法的数值,我们称为实际参数

    我们看下面的两段代码,来明确下参数传递的过程:

    public class ArgumentsDemo01 {
        public static void main(String[] args) {
            int a=5;
            int b=10;
            change(a, b);//调用方法时,传入的数值称为实际参数
            System.out.println("a=" + a);
            System.out.println("b=" + b);
        }
    
        public static void change(int a, int b){//方法中指定的多个参数称为形式参数
            a=200;
            b=500;
        }
    }

    结果:

    a=5
    b=10

    再看另一段代码

    public class ArgumentsDemo02 {
        public static void main(String[] args) {
            int[] arr = { 1, 2, 3 };
            change(arr);// 调用方法时,传入的数值称为实际参数
            
        for (int i = 0; i < arr.length; i++) {
                System.out.println(arr[i]);
            }
        }
    
        public static void change(int[] arr) {// 方法中指定的多个参数称为形式参数
            for (int i = 0; i < arr.length; i++) {
                arr[i] *= 2;
            }
        }
    }    

    程序的运行结果如下:

    2
    4
    6

    参数传递图解

    通过上面的两段程序可以得出如下结论:

    •   当调用方法时,如果传入的数值为基本数据类型(包含String类型),形式参数的改变对实际参数不影响
    •   当调用方法时,如果传入的数值为引用数据类型(String类型除外),形式参数的改变对实际参数有影响

     参考资料:http://www.runoob.com/java/java-object-classes.html

  • 相关阅读:
    ERROR 3009 (HY000): Column count of mysql.user is wrong. Expected 45, found 43. Created with MySQL 5
    centos mysql忘记密码找回(仅限mysql5.7)
    采购文件中 RFI、RFQ、RFP、IFB的区别
    VS2017安装时自动退出
    centos 虚拟机中修改屏幕分辨率
    Solved Unable to copy the source file ./installer/services.sh to the destination file /etc/vmware-t
    Idea实用功能手记
    mybatis,mybatis-generator,mybatis-plus手记
    springboot常用方法手记
    springboot日常问题处理手记
  • 原文地址:https://www.cnblogs.com/Young111/p/9904938.html
Copyright © 2011-2022 走看看