Java复习4 面向对象编程:类定义、重载、构造、包、访问权限修饰符、String类、Arrays类

4.面向对象编程

4.1.面向对象编程的三大特征

封装,继承,多态

4.2.类的定义

4.2.1类的基本结构

1.类的声明:
1)abstract或final:前者指出所定义的是抽象类,后者指出所定义的是最终类,不能被继承。
2)extends 父类名:指出所定义的类继承于哪一个父类,Java是单继承的,后面只能跟一个父类

4.2.2成员变量和局部变量

由类和方法的定义可知,在类和方法中均可定义属于自己的变量。类中定义的变量是成员变量,而方法中定义的变量是局部变量。类的成员变量与方法中的局部变量是有一定区别的。

(1)从语法形式上看,成员变量是属于类的,而局部变量是在方法中定义的变量或是方法的参数;成员变量可以被public、private、static等修饰符所修饰,而局部变量则不能被访问控制修饰符及static所修饰;成员变量和局部变量都可以被final所修饰。
(2)从变量在内存中的存储方式上看,成员变量是对象的一部分,而对象是存在于堆内存的,而局部变量是存在于栈内存的。
(3)从变量在内存中的生存时间上看,成员变量是对象的一部分,它随着对象的创建而存在,而局部变量随着方法的调用而产生,随着方法调用的结束而自动消失。
(4)成员变量如果没有被赋初值,则会自动以类型的默认值赋值有一种情况例外,被final修饰但没有被static修饰的成员变量必须显式地赋值);而局部变量则不会自动赋值,必须显式地赋值后才能使用

4.2.3成员方法

1)方法的声明

  • static:用static修饰的方法称为类方法,通过类名引用,即类名.方法名(参数列表);没有被static修饰过的方法称为实例方法,通过对象引用,即对象名.方法名(参数列表);
  • final:说明所定义的方法不能覆盖。
  • abstract:说明所定义的方法为抽象方法,此时方法不能有是实现体。

2)方法调用中的参数传递
在Java中,方法调用的参数(无论是基本数据类型还是引用类型的参数)都是值传递。

  • 参数为基本数据类型:直接得到副本
  • 参数为对象类型:传递对应变量的值,即某个对象的引用(实际占用的内存地址),如果方法内对该参数指向的对象进行了修改,这种修改对该对象是永久性的。(如果修改的是类变量的值,那么这种修改对该类的所有对象是永久性的)
  • 参数为数组类型:和对象一样,传递数组的引用。如果方法内对该参引用的数组对象的元素进行了修改,这种修改是永久性的。(注:在将数组对象传入方法,进行数组元素修改时,要用数组名+下标的形式直接引用数组元素进行修改。)二维数组转置矩阵如下:
public class App_1 {
    public static void main(String args[]) {
        int[][] a = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
        int[][] b = new int[3][3];
        Trans A = new Trans();
        b = A.trans(a);
        for (int i = 0; i < b.length; i++) {
            for (int j = 0; j < b[i].length; j++) {
                System.out.print(b[i][j] + " ");
            }
            System.out.println();
        }

    }
}
    class Trans {
        public  int[][] trans(int[][] array) {
            for (int i = 0; i < array.length; i++) {
                for (int j = 0 ; j < array[i].length; j++) {
                    int temp = array[i][j];
                    array[i][j] = array[j][i];
                    array[j][i] = temp;
                }
            }
            return array;
        }
    }
4.2.4重载

方法的参数列表不同。

4.2.5构造方法

构造方法就是类构造对象时调用的方法,主要用来实例化对象。

  • 1.特殊性:
    (1)构造方法的方法名与类名相同;
    (2)构造方法没有返回值,但不能写void
    (3)构造方法的主要作用是完成对类对象的初始化工作;
    (4)构造方法一般不能由编程人员显式地直接调用,而是用new来调用;
    (5)在创建一个类的对象的同时,系统会自动调用该类的构造方法为新对象初始化。
    (6)构造方法的优先级一般比代码块低
    (7)不能被static、final、synchronized、abstract和native修饰。
    (8)类中必定有构造方法,若不写,系统自动添加无参构造方法。接口不允许被实例化,所以接口中没有构造方法。
    (9)构造方法可以被重载。
    (10)构造方法不能被子类继承。
  • 2.默认构造方法
    (1)一旦用户为该类定义了构造方法,系统就不再提供默认的构造方法,这是Java的覆盖(overriding)所致。
    (2)若在一个类里只定义了有参数的构造方法,但却调用无参数的构造方法创建对象,则编译不能通过。
    (3)构造方法的重载
    (4)从一个构造方法调用另一个构造方法
public class App_2 {
    public static void main(String[] args) {
        Cylinder volu = new Cylinder();
    }
}

class Cylinder
{
    private double r;
    private int h;
    private double pi=3.14;
    String color;
    public Cylinder()
    {
        this(2.5, 5, "red");//用this来调用另一个构造方法
        System.out.println("无参构造方法被调用");
    }

    public Cylinder(double _r,int _h,String _str)
    {
        System.out.println("有参构造方法被调用");
        r = _r;
        h = _h;
        color=_str;
    }
}
//注:用this()调用其他构造方法时,它必须作为构造方法中的第一条语句。
4.2.6对象
  • 对象的创建:类名 对象名;

  • 对象实例化:变量名 = new 类名(参数列表);
    此时,系统要做的工作:1.分配空间,将成员变量初始化为默认值,如整型变量为0,逻辑类型变量为false,引用类型变量为null。2.也可执行显式初始化,即执行类成员变量声明时带的赋值表达式。3.也可以通过相应的构造函数完成初始化。

  • 对象的使用: 对象.成员变量/成员方法(参数列表)
    关于类与对象的一些问题
    this表⽰什么含义?
    (1)this关键字代表本类对象的⼀个引⽤,谁调⽤this所在的⽅法,this就代表谁
    (2)this的使⽤场景
    A:⽤于区分同名成员变量和局部变量;
    B:在定义函数时,该函数内部要⽤到调⽤该函数的对象时,因为此时对象还没建⽴,故this代表此对象 C:构造函数间调⽤,this(参数)必须作为第⼀条语句存在。
    什么叫匿名对象,⼀般在什么情况下使⽤匿名对象?
    ⼀个没有名字的对象, 创建了⼀个对象出来,没有赋给⼀个变量;
    特点:对⽅法或字段只进⾏⼀次调⽤时;
    可作为实际参数进⾏传递;
    只在堆⾥⾯开辟存储区域,只能使⽤⼀次, 使⽤完就被销毁了;
    何时使⽤?只拿来⽤⼀次!!
    new Person();表⽰匿名对象,没有名字的对象
    new Person().age = 17;//使⽤⼀次之后就被销

4.2.7static

static称为静态修饰符,它可以修饰类中的成员。被static修饰的成员称为静态成员,也称为类成员,而不用static修饰的成员称为实例成员。

  • 1.实例成员:在类定义中如果成员变量或成员方法没有用static来修饰,则该成员就是实例成员。
  • 2.静态变量(类变量):

1)用static修饰的成员变量称为静态变量,也称为类变量。类变量被类的所有对象所共有,即任何一个对象修改了静态变量,那么其他对象访问的是该变量修改后的值。
2) 类中若含有静态变量,则静态变量必须独立于方法之外,就像其他高级语言在声明全局变量时必须在函数之外声明一样。
3) 静态变量不需要实例化就可以使用。当然,也可以通过实例对象来访问静态变量。使用格式有如下两种:

 类名.静态变量名;
 对象名.静态变量名;
  • 3.静态方法(类方法):

  • 几重含义
    1)非static的方法是属于某个对象的方法,在创建这个对象时,对象的方法在内存中拥有属于自己专用的代码段。而static的方法是属于整个类的,它在内存中的代码段将被所有的对象所共用,而不被任何一个对象所专用。
    2)由于static方法是属于整个类的,所以它不能操纵和处理属于某个对象的成员,而只能处理属于整个类的成员,即**static方法只能访问static成员变量或调用static成员方法,或者说在静态方法中不能访问实例变量与实例方法。**但实例化后可以访问非静态成员,即new一个对象后通过对象调用。
    3)在静态方法中不能使用this或super。因为this是代表调用该方法的对象,但现在静态方法既然不需要对象来调用,this也自然不应存在于静态方法内部。
    4)调用静态方法时,可以使用类名直接调用,也可以用某一个具体的对象名来调用。其格式如下:

 类名.静态方法名();
 对象名.静态方法名();

静态习题

5)现在有了静态方法的知识后,读者现在可以理解main()方法的定义了。由于Java虚拟机需要在类外调用main()方法,所以该方法的访问权限必须是public;又因为Java虚拟机运行时系统在开始执行一个程序前,并没有创建main()方法所在类的一个实例对象,所以它只能通过类名来调用main()方法作为程序的入口,即调用main()方法的是类名,而不是由类所创建的对象,因而该方法必须是static的。练习

  • 4.静态语句块(静态初始化器)
    1)静态初始化器是由关键字static修饰的一对花括号“{}”括起来的语句组。
    2)静态初始化器不是方法; 对类自身进行初始化;在所属的类被加载入内存时由系统调用执行;在类被加载入内存时只执行一次,与创建多少个对象无关;如果有多个静态初始化器,则它们在类的初始化时会依次执行。
    3)在对象生成前就分配了内存空间,先于对象的创建或对象成员变量的初始化。

4.2.对象的应用

1)对象的赋值和比较

//创建圆柱体类Cylinder,并对该类创建的对象进行赋值运算。
class Cylinder {
    //定义类Cylinder
    private static double pi = 3.14;
    private double radius;
    private int height;
    public Cylinder(double r, int h) {
        radius = r;
        height = h;
    }
    public void compare(Cylinder volu) //以对象作为方法 的参数
    {
        if (this == volu)//判断this与volu是否指向同一对象
            System.out.println("这两个对象相等");
        else
            System.out.println("这两个对象不相等");
    }
}
public class App_3 {
    public static void main(String[] args) {
        Cylinder volu1 = new Cylinder(1.0, 2);
        Cylinder volu2 = new Cylinder(1.0, 2);
        Cylinder volu3 = volu1;
        volu1.compare(volu2);//调用compare(),比较volul与volu2是否相等
        volu1.compare(volu3);//调用compare(),比较volul与volu3是否相等
    }
}
//注:引用变量volu1与volu2的值分别是这两个对象在内存中的首地址,显然它们是不相等的。而volu1和volu3是指向同一个对象的两个变量,它们的值是同一对象在内存中的首地址,所以它们是相等的。

2)引用变量作为方法的返回值
例子
3)类类型的数组
以对象数组作为参数传递给方法,返回对象数组中最小的成员变量。
例子

4.3.包

  • package语句
    1)使用package语句来指出所定义的类属于某个特定的包,格式:package 包名;
    2)package语句必须放在程序中非注释代码的第一行;package语句只能有一个或没有;源程序没有package语句的,则源程序中所定义的类都属于默认包;

  • import语句
    1)使用import语句来引入包成员:
    格式1:import 包名.类名;
    格式2:import 包名.*;
    使用包中的多个类时,可以使用通配符" * ",来引入包中的所有类。但“∗”只能表示本层次的所有类,不包括子层次下的类。
    2) import语句必须放在源程序任何类声明之前,但要在package语句之后;一个源程序可以有多个import语句。

4.4.访问权限修饰符

  • private:无法从该类的外部访问到该类内部的成员,而只能被该类自身访问和修改,而不能被任何其他类(包括该类的子类)获取或引用。
  • friendly:类和类成员的默认修饰符,含义为只能被类本身和同一个包中的类所访问。
  • protected:可以被类本身、该类的子类(无论是否在同一个包中)和同一个包中的类所访问。
  • public:同一类,同一包,不同包中的子类,不同包中的非子类。

4.5.常用类

  • Object类
    常用方法:
    1.public boolean equals(Object obj)
    “==”运算符用于比较两个变量本身的值,即两个对象在内存中的首地址,而equals()方法则是比较两个字符串中所包含的内容是否相同;
  • String类与StringBuffer类
    -关于String类
  1. String 类中重写了 equals() 方法用于比较两个字符串的内容是否相等。
  2. String 中 == 比较引用地址是否相同,equals() 比较字符串的内容是否相同。
  3. String 类是不可改变的,所以你一旦创建了 String 对象,那它的值就无法改变了。
  4. String类是final类,不可以有子类(final不能有子类√
  5. String类在java.lang包下,所以不需要导入。
  6. 字符串具有共享性。
String a1 = "akb";
String a2 = "akb";
 
char[] array = new char[]{'a','k','b'};
String a3 = new String(array);
System.out.print(a1 == a2);//输出为true
System.out.print(a2 == a3);//输出为false
System.out.print(a1 == a3);//输出为false

解释:
1.a1和a2是使用直接创建的方式去创建的字符串,所以会在字符串常量池里有记录,第一次a1去创建的时候,会发现在常量池里面找不到akb这个值,然后会初始化一个,另外开辟一个内存,当a2以相同的创建方式去创建一个内容一样的字符串的时候,它首先会去常量池里面去找有没有内容一样的,这里就是字符串的共享性,既然a1已经是有的,那么直接拿过来使用就可以了,也不会再重新开辟一个内存,防止浪费。所以就地址值上面来说,a1是等于a2的,所以第一行输出为true,后面new 出来的不在常量池当中,而是存在在堆当中所以就此而言,内存地址值是不一样的。

2、对于==符号来说,引用数据类型是比较的地址值,基本数据类型来说是比较的数值

3、直接使用双引号创建的字符串是存在在堆中的字符串常量池中,内存还会再将其转换为字节数组。但是保存的内存地址值就是常量池当中的String类的对象的地址值

4、使用new创建出来的字符串,是在堆当中开辟了一个新的地址,不在常量池当中,本身保存的也是字节形式的数组的地址值

参考链接:链接1

String s1 = "Hello";              // String 直接创建
String s2 = "Hello";              // String 直接创建
String s3 = s1;                   // 相同引用
String s4 = new String("Hello");  // String 对象创建
String s5 = new String("Hello");  // String 对象创建
 
s1 == s1;         // true, 相同引用
s1 == s2;         // true, s1 和 s2 都在公共池中,引用相同
s1 == s3;         // true, s3 与 s1 引用相同
s1 == s4;         // false, 不同引用地址
s4 == s5;         // false, 堆中不同引用地址
 
s1.equals(s3);    // true, 相同内容
s1.equals(s4);    // true, 相同内容
s4.equals(s5);    // true, 相同内容
  • 关于Java StringBuffer 和 StringBuilder 类
    当对字符串进行修改的时候,需要使用 StringBuffer 和 StringBuilder 类。
    和 String 类不同的是,StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象。
  • Array类
    最佳参考:Arrays
  • Math类
  • Random类
  • Date类
    …待更新
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值