JAVA学习记录(四)—— 类和对象

  • 面向过程:当需要实现一个功能的时候,每一个具体的步骤都要亲历亲为,详细处理每一个细节。
  • 面向过程:当要实现一个功能的时候,不关心具体的步骤,而是找一个已经具有该功能得人,来帮我做事。
import java.util.Arrays;

public class Demo01PrintArray {
    public static void main(String[] args) {
        int[] array = {10,20,30,40,50}; //数组的静态初始化

        //打印格式为:[10, 20, 30, 40, 50];

        //面向过程 -- 每一个符号都要亲历亲为
        System.out.print("[");
        for (int i = 0; i < array.length; i++) {
            if (i == array.length - 1) {
                System.out.println(array[i] + "]");// 如果是最后一元素
            } else {
                System.out.print(array[i] + ", "); //如果不是最后一个元素
            }
        }
        System.out.println("=====================");
        //面向对象
        //找一个JDK提供好的Arrays类
        //其中有一个toString方法,直接就能把数组变成想要的格式的字符串
        System.out.println(Arrays.toString(array));
    }
}
  • 面向对象的语言中有三大基本特性:封装、继承和多态。

什么是类?
  • 类:是一组相关属性行为的集合,可以看成是一类事物的模板,使用事物的属性特征和行为特征来描述该类事物。
  • 属性:该事物的状态信息。
  • 行为:该事物能够做什么。
什么是对象?
  • 对象:是一事物的具体体现。对象是类的一个实例,必然具备该事物的属性和行为。
定义一个student类
public class Student {
    /**
     * 定义一个类,用来模拟“学生”事物,其中就有两个组成部分
     * 属性(是什么): 性别、年龄。。。<特征描述>
     * 行为(能做什么):吃饭、睡觉、学习
     *
     * 对应的到java的类中
     * 属性 ——》 成员变量
     *       String name; //姓名
     *       int age; //年龄
     * 行为 ——》 成员方法
     *       public void eat(){}    //吃饭   在成员方法中,static关键字要删掉
     *       public void sleep(){}  //睡觉
     *       public void study(){}  //学习
     */
    //先写成员变量
    String name; //姓名   
    int age;     //年龄
    //再写成员方法
    public void eat(){};   //吃饭
    public void sleep(){}; //睡觉
    public void study(){}; //学习
}

注意事项:

  • 1、此前的变量都叫做局部变量,都是写在方法内部的,存放在栈上一旦直接写在类里,就叫做成员变量,存放在堆上。
  • 2、成员方法不要写static关键字
如何使用一个类
  • 通产情况下,一给类并不能直接使用,需要根据类创建一个对象,才能使用。
  • 1、导包:指出需要使用的类,在什么位置;
import 包名称.类名称
对于和当前类属于同一个包的情况,可以省略导包语句不写。
  • 2、创建:格式
类型名 对象名 = new 类名称();
Student stu = new Student(); ——》 根据Student类,创建了一个名为stu的对象。
  • 3、使用:分为两种情况
使用成员变量: 对象名.成员变量名
使用成员方法: 对象名.成员方法名(参数)
public class Demo02Student {
    public static void main(String[] args) {
        //1.导包
        //此处我的Student类与我的Demo02Student处于同一个包下,所以省略导包语句不写

        //2.创建
        Student stu = new Student();

        //3.使用对象的成员变量
        System.out.println(stu.name);  //默认值为null\
        System.out.println(stu.age);   //默认值为0
        System.out.println("=====================");
        //改变对象当中的成员变量数值内容
        stu.name = "周"; //将右侧的字符串,赋值交给stu对象当中的name成员变量
        stu.age = 23;
        System.out.println(stu.name);
        System.out.println(stu.age);
        System.out.println("=====================");
        //4、使用对象的成员方法
        stu.eat();
        stu.sleep();
        stu.study();
    }


}
  • 如果成员变量没有进行赋值,那么将会有一个默认值。
手机类练习
package Class_object.demo02;
/*
定义一个类,用来模仿“手机”事物
属性:品牌、价格、颜色
行为:打电话、发短信

对应到类中
成员变量(属性)
    String brand; //品牌
    double price; //价格
    String colour; //颜色
成员方法(行为)
    public void call(String who){} //打电话
    public void sendMessage(){}    //群发短信
 */
public class Phone {

    //成员变量
    String brand;  //品牌
    double prince; //价格
    String colour; //颜色

    //成员方法
    public void call(String who){
        System.out.println("给" + who + "打电话");
    }
    public void sendMessage(){
        System.out.println("群发短信");
    }
}
package Class_object.demo02;

public class Demo01PhoneOne {
    public static void main(String[] args) {
        //根据Phone类创建一个one对象
        Phone one = new Phone();
        System.out.println(one.brand);  //null
        System.out.println(one.colour); //null
        System.out.println(one.prince); //0.0
        System.out.println("==============");
        one.brand = "苹果";
        one.colour = "红色";
        one.prince = 8848;
        System.out.println(one.brand);
        System.out.println(one.colour);
        System.out.println(one.prince);
        System.out.println("==============");
        one.call("周");
        one.sendMessage();
    }
}
  • 我们通过画图来清晰的看到类在内存空间中是如何运作的
  • 一个对象的内存图
    在这里插入图片描述
  • 另外还有两种情况
  • 1、两个对象使用同一个方法的内存图
  • 2、两个引用指向同一个对象的内存图(两个对象引用指向同一个对象空间)
既然任何数据类型都能作为方法的参数或返回值,那么能否用自定义的Phone这个类作为方法的参数类型?
  • 自定义的类最为方法的参数
public static void main(String[] args) {
        Phone one = new Phone();
        one.brand = "苹果";
        one.price = 8848.0;
        one.colour = "白色";

        //我现在有“苹果”这样一个手机叫做one,我能否将它作为一个参数往method的方法中进行传递?
        method(one); //one当中是一个地址值

    }

    public static void method(Phone param){  //这里param收到的也是一个地址值
        System.out.println(param.brand);
        System.out.println(param.price);
        System.out.println(param.colour);

    }
  • 自定义的类作为方法的返回值
  • 当使用一个对象类型作为方法的返回值时,返回值其实就是对象的地址值。
public static void main(String[] args) {
        Phone two = getPhone();
        System.out.println(two.brand);
        System.out.println(two.price);
        System.out.println(two.colour);
    }
    public static Phone getPhone(){
        Phone one  = new Phone();
        one.brand = "苹果";
        one.price = 8848;
        one.colour = "蓝色";
        return one;  //谁调用了getPhone,就把one的地址交给谁
    }

成员变量和局部变量的区别
  • 1、定义的位置不一样:局部变量在方法的内部;成员变量在方法的外部,直接写在类当中。
  • 2、作用范围(作用域)不一样:局部变量只在方法当中可以使用,出了方法就不能用了;成员变量是在类当中,整个类都可以使用。
  • 3、默认值不一样:局部变量没有默认值,想要使用,必须进行初始化赋值;成员变量未赋值时会有默认值。
  • 4、内存位置不一样:局部变量位于栈内存;成员变量位于堆内存
  • 5、生命周期不一样:局部变量随着方法进栈而诞生,随着方法出栈而消失;成员变量随着对象创建而诞生,随着对象被垃圾回收而消失。(垃圾回收是指,这个对象再也没有用处时,JVM会在合适时机将其清理掉,垃圾回收的时机java程序员是无法直接控制的)
private关键字的作用及使用(直接访问/间接访问)
  • 当定义Person的年龄时,无法阻止不合理的值被设置进来
public class Person {
    String name;   //姓名
    int age;       //年龄
    public void show(){
        System.out.println("我叫," + name + ",年龄:" + age);
    }
}
public class Demo03Person {
    public static void main(String[] args) {
        Person person  = new Person();
        person.show();

        person.name = "周";
        person.age = -4;         //此时会打引出来 我叫,周,年龄:23
                                 //但这不符常理,因为年龄并不能为负,但是我们在定义Person类中的age时使用的是int,所以允许任何整数
    }
}
  • 要解决这个问题,使用关键字private关键字将需要保护的成员变量进行修饰
public class Person {
    String name;   //姓名
    private int age;       //年龄
    public void show(){
        System.out.println("我叫," + name + ",年龄:" + age);
    }
}
  • 一旦使用了private进行修饰,那么本类当中仍然可以随意访问,但超出了本类范围之外就不能再直接访问即person.age这种访问方法在Person这个类里可以使用但在Demo03Person这个类里无法使用。
  • 既然无法直接访问,就需要进行间接访问
  • 间接访问private成员变量,就是定义一对getter/setter方法
public class Person {
    String name;   //姓名
    private int age;       //年龄
    public void show(){
        System.out.println("我叫," + name + ",年龄:" + age);
    }

    //成员方法专门用于向age设置数据
    public void setAge(int num){
        if(num < 100 && num >= 0){
            age = num;
        }else{
            System.out.println("数据不合理");
        }
    }
    //成员方法专门用于获取age的数据
    public int getAge(){
        return age;
    }
}
public class Demo03Person {
    public static void main(String[] args) {
        Person person  = new Person();
        //person.show();
        person.name = "周";
        //person.age = -4; //直接访问private内容,是错误写法
        person.setAge(-24);
    }
}
  • 注意:对于getter/setter方法名称必须遵守getxxx/setxxx命名规则,且对于getter方法来说,不能有参数,返回值类型和成员变量对应;对于setter来说,不能有返回值,参数类型和成员变量对应
  • 对于基本类型当中的boolean类型,getter要写成isxxx的格式!!!
//boolean类型的getter//setter方法略有不同
    public void setMale(boolean b){
        male = b;
    }
    public boolean isMale(){
        return male;
    }
public class Demo04Student {
    public static void main(String[] args) {
        Student stu = new Student();
        
        stu.setMale(true);
        System.out.println(stu.isMale());
    }
}

this关键字的作用
  • 当方法的局部变量和类成员变量重名的时候,根据“就近原则,优先使用局部变量”
  • 如果需要访问本类当中的成员变量,需要使用关键字this.成员变量名
public class Person {
    
    String name;
    public void sayHello(String name){
        System.out.println(name + ", 你好,我是" + this.name);  
    }
}
  • 通过谁调用的方法,谁就是this

构造方法
  • 构造方法是专门用来创建对象的方法,当我们通过关键字new来创建对象时,其实就是在调用构造方法

  • 格式:

  • public 类名称(参数类型 参数名称){方法体}

  • 注意事项:

    • 1、构造方法的名称必须和所在的类名称完全一样,大小写也要相同
    • 2、构造方法不要写返回值类型,void也不要写
    • 3、构造方法不能return一个具体的返回值
    • 4、如果没有编写任何构造方法,编译器将会默认赠送一个构造方法没有参数,方法体什么事情都不做
    • 5、一旦编写了至少一个构造方法,那么编译器将不再赠送
    • 6、构造方法也是可以进行重载的
public class Student {
    //成员变量
    private String name;
    private int age;
    //无参数的构造方法
    public Student(){
        System.out.println("无参构造方法执行了");
    }
    //重载
    //全参数的构造方法
    public Student(String name, int age){
        System.out.println("全参构造方法执行了");
        this.name = name;
        this.age = age;
    }
    public void setName(String name){
        this.name = name;
    }
    public String getName(){
        return name;
    }
    public void setAge(int age){
        this.age = age;
    }
    public int getAge(){
        return age;
    }
}
public class Demo02Student {
    public static void main(String[] args) {
        Student stu1 = new Student();   //无参构造
        System.out.println("================");
        Student stu2 = new Student("周",23);  //全参构造
        System.out.println("姓名" + stu2.getName() + ", 年龄," + stu2.getAge());
        //如果需要改变对象当中的数据内容,仍然还需要使用stexxx方法
        stu2.setAge(24);
        System.out.println("改变年龄");
        System.out.println("姓名" + stu2.getName() + ", 年龄," + stu2.getAge());
    }
}

综合练习:如何定义一个标准的学生类

一个标准的类,通常要满足下面四个组成部分

  • 1、所有的成员变量都要使用private关键字修饰
  • 2、为每一个成员变量编写一对Getter/Setter方法
  • 3、编写一个无参数构造方法
  • 4、编写一个全参数构造方法

一个标准的类也叫做Java Bean

  • 我们在新建一个类的时候,只需要写好它的成员变量,之后通过快捷键alt + inster在菜单里可以选择自动生成Getter/Setter方法和无/全参构造方法

通过习题了解一些详细概念

1、阅读如下代码。请问,对语句行test.hello(),描述正确的有:

package NowCode;
class Test{
    public static void hello(){
        System.out.println("hello");
    }
}
public class MyApplication{
    public static static void main(String[] args){
        Test test = null;
        test.hello();
    }    
}
  • A、编译能通过,并正确运行
  • B、以你为使用了未初始化的变量,所以不能编译通过
  • C、以错误的方式访问了静态方法
  • D、能编译通多,但因变量为null,不能正常运行

  解析:此处正确答案为A,编译能通过,并正确运行,我们首先看main函数处,Test test = null这段语句表示new一个test不指向任何对象(空对象),所以如果此时我们使用test.来调用的话会出现空指针异常即NullPointerException在此题中,我们这里在Test类中写的hello方法为static类型,这样此hello方法就不依赖于对象,可以通过类直接调用。 重点:静态方法不依赖于对象。

2、以下代码的运行结果是:

public static void main(String[] args){
    String s;
    System.out.println("s=" + s);
}

  解析:结果为:由于String s 没有初始化,代码不能编译通过

3、如下代码会编译报错的原因是什么?

public class Test { 
    public int aMethod(){
        static int i = 0;
        i++; 
        return i;
    } 
public static void main(String args[]){
    Test test = new Test(); 
    test.aMethod(); 
    int j = test.aMethod();
    System.out.println(j);
    } 
}

  解析:静态的变量是不依赖于对象的,但此处aMethod方法的调用是需要引用new一个对象,所以static int i = 0是不能放在此处的。若将方法改成public static int aMethod(),则此处依然为报错,但此时是因为,i是定义在方法里面,属于局部变量,局部变量是存放在栈上的,而static存放的变量是在方法区,所以此处冲突。

4、编译运行下面代码,会出现什么情况?

public class Pvf{
    static boolean Paddy;
    public static void main(String args[]){
        System.out.println(Paddy);
    }
}

  解析:定义了一个静态类型的Boolean类型变量,同时输出它。此处的Paddy属于类变量。所以会编译通过并输出结果false。

5、已知如下类,那些使用是正确?

public class Test{
    private float f=1.0f;
    int m = 12;
    static int n = 1;
    public static void main(String args[]){
        Test t = new Test();
    }
}
  • A、t.f = 1.0
    此处不能这样使用,因为应该写为t.f = 1.0f
  • B、this.n
    n是一个静态的,this表示的是当前对象的引用,所以不能调用n
  • C、Test.m
    通过类名调用,除非m是静态时,才可以访问
  • D、Test.n

6、以下程序代码的说明正确的是?

public class HasStatic{                    //1
    private static int x = 100;            //2
    public static void main(String args[]){//3
        HasStatic hsl = new HasStatic();   //4
        hsl.x++;                           //5
        HasStatic hs2 = new HasStatic();   //6
        hs2.x++;                           //7
        has1 = new HasStatic();            //8
        hs1.x++;                           //9
        HasStatic.x--;                     //10
        System.out.println("x =" + x);     //11
    }
}
  • A、程序通过编译,输出结果为:x=102
  • B、程序通过编译,输出结果为:x=103
  • C、10行不能通过编译.因为x星私有静态变量
  • D、5行不能通过编译.因为引用了私有静态变量

  解析:x是静态变量

7、在JAVA中,假设A有构造方法A(int a),则在类A的其他构造方法中调用该构造方法和语句格式应该为()

  • A.this.A(x)
  • B.this(x)
  • C.super(x)
  • D. A(x)

  解析:在类A的其他构造方法中调用该构造方法只能用this,this有三种用法:1、访问数据this.data;2、访问普通方法this.func();3、调用它的构造方法this()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值