自学-Java程序设计(7)

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

这次讲的是面向对象程序设计

java是面向对象的程序设计语言,它为用户提供了类、接口和数组,这些都是不同于基本数据类型的类型。

  • 类和对象

    • 类的定义:类的定义也称为类的声明。类中有两部分元素,分别是数据成员变量和成员方法。类定义的一般格式如下。

      修饰符 class 类名 [enxtends 父类名] {
        修饰符 类型 成员变量1;
        修饰符 类型 成员变量2;
        .....
        修饰符 类型 成员方法1 (参数列表) {
          方法体
        }
        修饰符 类型 成员方法2 (参数列表) {
          方法体
        }
        ......
      }
      复制代码

      其中class是关键字,表明其后定义的是一个类。含有class的这一行称为类头,后面大括号括住的部分称为类体。class前的修饰符可以有多个,用来限定所定义的类的使用方式。类名是用户为该类所起的名字,它必须是一个合法的标识符,并尽量遵从命名约定。extends是关键字。如果所定义的类是从某一个父类派生而来,那么,父类的名字要写在extends之后。

      类定义中的修饰符是访问权限修饰符,包括public、private和protected,也可以补血,表示是默认修饰符,它们既可以用来修饰类,又可以修饰类中的成员,修饰符决定所修饰成员在程序运行时被访问的方式。具体的

      • public修饰的成员是工友的,也就是它可以被其他任何对象访问
      • private的成员只能被这个类本身访问,在类外是不可见。
      • protected修饰的成员是受保护的,只可以被同一包及其子类的实例对象访问。
      • 如果不写任何修饰符,则表示默认的,相应的成员可以被所在包中的各类访问。
      public class Person {
        private String name;
        private int age;
        private String gender, phonenumber;
      }
      复制代码
    • 构造方法

      构造方法是一类特殊的方法,有特殊的功能。构造方法的名字与类名相同,没有返回值,在创建对象实例时通过new运算符自动调用。同时为了便于创建实例,一个类可以有多个具有不同参数列表的构造方法,即构造方法可以重载。

      构造方法不能说明为native、abstract、synchronized或final类型,通常说明为public类型的。构造方法不能从父类继承。另外,构造方法没有返回值类型。一般来讲,构造方法应该为所有的成员变量赋初值,成员变量的值亦称为对象的属性值。

      public class Xyz {
        int x;
        public Xyz() {x = 0;}
        public Xyz (int i) { x = i;}
      }
      复制代码
      • 默认的构造函数

        每个类都必须至少有一个构造方法。如果程序员没有为类定义构造方法,系统就会自动为该类生成一个默认的构造方法。默认构造方法的参数列表及方法体均为空,所生成的对象的各属性也为零或空。如果类定义中已经含有一个或多个构造方法,则系统不会再自动生成默认的构造方法了

      class BankAccount {
        String ownerName;
        int accountNumber;
        float balance;
      }
      public class BankTester {
        	public static void main(String args[]) {
            BankAccount myAccount = new BankAccount(); //调用默认的构造方法
            System.out.printIn("ownerName="+myAccount.ownerName);
            System.out.printIn("accountNumber="+myAccount.accountNumber);
            System.out.printIn("balance="+myAccount.balance);
          }
      }
      //定义类BankAccount,并在类BankTester中创建了实例myAccount,因为在类定义中没有写任何构造方法,所以这里要调用系统给出的默认构造方法,也就是说myAccount的各个域的值为空或零。
      //输出的结果为: ownerName=null; accountNumb=0; balance=0.0;
      复制代码
      • 构造方法重载

        在进行对象实例化时可能会遇到许多不同情况,于是要求针对所给定的不同的参数,调用不同的构造方法,这时,可以通过在一个类中同时定义若干个构造方法,亦即对构造方法进行重载进行实现。有些构造方法中会有重复的代码,或者一个构造方法可能包含另一个构造方法中的全部代码,为了能够简化代码的书写,可以在其中一个构造方法中引用另一个构造方法。可以使用关键字this来指代本类中的其他构造方法。

      public class Student {
        String name;
        int age;
        public Student(String s, int n) {//第一个构造方法
          name = s;
          age = n;
        }
        public Student(String s) {//第二个构造方法
          this(s, 20);
        }
        public Student() {//第三个构造方法
          this("UnKnown");
        }
      }
      复制代码
    • this引用

      this除了可以用在构造方法中之外,还可以用来指明要操作的对象本身。

    • 对象的创建和初始化

      声明变量后,在内存中为其建立了一个引用,此时它不指向任何内存空间。对象的引用也称为对象的句柄。之后,需要使用new申请相应的内存空间,内存空间的大小依class的定义而定,并将该段内存的首地址赋给刚才建立的引用。换句话说,用class类型声明的变量并不是数据本身,而只是对数据的引用,要用new来进一步创建类的实例或对象本身。

      通过new为新对象分配空间时,就是要调用类的构造方法。

      创建对象实例的格式如下:

      ​ 变量名 = new 类名 (参数列表);

      ​ 也可以与变量声明合在一起使用;

      ​ 类名 变量名 = new 类名(参数列表);

      当通过new为一个对象分配空间时,如果构造方法中没有为成员变量提供初值,则进行自动初始化。对于数值变量,赋初值0;对于布尔变量,赋初值false;对于引用,即对象类型的任何变量,使用一个特殊的值null作为初值。

      定义类时,可以对成员变量进行显式的初始化,即在声明这些变量的同时,直接给出它们的初值。

      public class Initialized {
        private int x = 5;
        private String name = "Fred";
        private Date created = new Date();
        ...
      }
      复制代码
  • 定义方法

    对对象的操作体现在成员方法上。说明为private的成员变量,在类外,不能通过点操作符志杰访问,必须通过成员方法才能访问

    关于定义方法的说明如下:

    ​ 方法名必须时一个合法的标识符

    ​ 返回类型时方法返回值的类型。如果方法不返回任何值,则应该声明为void。Java对待返回值的要求很严格,方法返回值必须与所声明的类型相匹配。如果方法声明有返回值,比如说是int,那么方法从任何一个分支返回时都必须返回一个整数值。

    ​ 修饰符段可以含有几个不同的修饰符,其中限定访问权限的修饰符包括public、protected和private。

    ​ 参数列表时传送给方法的参数表。表中各元素间以逗号分隔,每个元素由一个类型和一个标识符表示的参数组成。

    ​ 块表示方法体,是要实际执行的代码段,是由一对大括号括起来的语句序列。方法体中一般使用return语句表示方法的结束。如果方法的返回类型不是void,则需要return语句中说明方法的返回值。

    • 按值传送

      调用方法时,通常会给方法传递一些值。传给方法的值称为实参,方法的参数列表中列出的值称为形参。

      Java按值传参。如果形参是基本数据类型的,则调用方法时,将实参的“值”复制给行参。返回时,行参的值并不会带回给实参,即在方法内对形参的任何修改,都不会影响实参的值。

      如果形参是引用,则调用方法时传递给形参时一个地址。即实参指向的对象的收地址。方法返回时,这个地址也不会被改变,但地址内保存的内容是可以改变的。因此,当从方法中退出时,所修改的对象内容也不会被改变。

    • 重载方法名

      允许多个方法使用同一个方法名,这就是方法名的重载。

      一个类中,如果有多个方法的名字是一样的,为了调用时不产生混乱,Java规定,方法的参数列表必须不完全相同。实际上,Java正式根据参数列表来查找适当的方法并进行调用的,这其中包括参数的个数及各参数的类型以及它们的顺序。一般地,方法名称加上方法的参数列表(包括方法中参数的个数、顺序和类型)称为方法签名,方法重载时,方法签名一定不能相同。

      重载方法有两条规则,分别如下所述:

      • 调用语句的实参列表必须足够判断要调用的是哪个方法。实参的类型可能要进行正常的扩展提升(如浮点数变为双精度数),但在有些情况下会引起混淆。
      • 方法的返回类型可以相同也可以不同。两个同名方法仅有返回类型不同,而参数列表完全相同,这是不够的,因为在方法执行前不知道能得到什么类型的返回值,因此也就不能确定要调用哪个方法。重载方法的参数列表必须不同。
  • 静态成员

    在类的定义中还可以定义一种特殊的成员,用static修饰,称为静态成员或类成员,包括静态变量和静态方法。静态成员是不依赖于对象的内容。

    • 静态变量

      将一个变量定义为静态变量的方法就是将这个变量标记上关键字static。

      静态变量是唯一为类中所有对象共享的变量。如果一个静态变量同时还被定义为public类型,那么其他类也同样可以使用这一变量。而且由于静态变量内存空间是在类的名义时就已经分配的,因此引用这一变量时设置无需生成该类的一个对象,而是直接利用类名来指向它。

    • 静态方法

      与静态变量类似,如果需要在尚未创建一个对象实例的时候就去引用方法方法的程序代码,那么标记上关键字static即可实现。这样的方法称为静态方法,或称为类方法。与之相对的,非静态方法有时也称为实例方法。静态方法不依赖于特定对象的行为。

      使用静态方法有两个特别的限制必须注意:

      • 由于静态方法可以在没有定义它所从属的类的对象的情况下加以调用,故不存在this值,因此,一个静态方法只能使用其内部定义的参数或静态变量,如果想使用非静态变量将因此编译错误。
      • 静态方法不能被重写。也就是说,在这个类的后代类中,不能有相同名称、相同参数列表的方法。
  • 包装类

    Java使用基本数据类型(如int、double、char和boolean)及类和对象来表示数据。要管理的数据仅有两类,即基本数据类型值及对象引用。但当想用处理对象一样的方法来处理基本类型的数据时,必须将基本类型值“包装”为一个对象。为此,Java提供了包装类。

    对于java中的每种基本数据类型,Java类库中都有一个对应的包装类。

    对应于void类型的包装类是Void。但和其他的包装类不一样的是,Void类不能被实例化,值表示void引用的概念。

    自动将基本数据类型转换为对应的包装类的过程称为自动装箱:

    Integer obj1;
    int num1 = 69;
    obj1 = num1; //自动创建Integer对象
    //逆向的转换称为拆箱(Unboxing),需要时也是自动完成的。
    Integer obj2 = new Integer(69);
    int num2;
    num2 = obj2; //自动解析出int型
    复制代码

    一般来说,基本数据类型与对象之间的赋值时不相容的。自动装箱与自动拆箱仅能在基本数据类型与对应的包装类之间。其他的情况,如将基本数据类型赋给对象引用变量,或时相反的过程,都会导致编译错误。

猜你喜欢

转载自juejin.im/post/7018103218882215966