Java拾贝第二天——面向对象

Java拾贝不建议作为0基础学习,都是本人想到什么写什么

面向对象的三大特性

封装性,继承性,多态性。

类的组成

public class 类名 {
    //成员变量
    int age;//数据类型 变量名;

    //成员方法
    public 返回值类型 方法名(传参) {
    String name;//局部变量
    //方法的内部被称为方法体
    }
}

定义在类中的变量名,也叫字段名,也叫成员变量 有本事名字再多一点

定义在方法中的属性称之为局部变量。

简单的栗子

public class Person {
    String name;
    int age;
    public void tell() {
        System.out.println("嘟嘟嘟~"+name+","+age);
    }
}
//你知道Person类中包含哪些内容吗?

面向对象的概念

可以把对象当作待涂鸦的纯白雕塑,其模板是固定的。

更多的内容需要后续进行加工补充。

继续用上述Person类举例,现在创建对象并且使用它(也叫实例化)

//实例化一个类👉类名 变量名=new 类名();

public class test2 {
    public static void main(String[] args) {
        Person p =new Person();//实例化一个对象p
    }
}
class Person{
    String name;
    int age;
    public  void tell() {
        System.out.println("嘟嘟嘟~"+name+","+age);
    }
}

现在已经实例化成功了,执行一下tell方法

要使用对象访问其属性值或方法操作如下
对象名.属性名;
对象名.方法名();

public static void main(String[] args) {
        Person p =new Person();
        p.tell();
    }
//嘟嘟嘟~null,0

调用成功了,打印结果有null和0的原因是还没有给变量赋值,所以输出的是属性的默认值。

现在需要修改其属性值使输出不再使用默认值。

public static void main(String[] args) {
        Person p =new Person();
        p.name="张三";
        p.age=18;
        p.tell();
    }
//嘟嘟嘟~张三,18

创建多个对象

public class test2 {
    public static void main(String[] args) {
        Person p1 =new Person();
        p1.name="张三";
        p1.age=18;
        p1.tell();

        Person p2 =new Person();
        p2.name="李四";
        p2.age=19;
        p2.tell();
    }
}
class Person{
    String name;
    int age;
    public  void tell() {
        System.out.println("嘟嘟嘟~"+name+","+age);
    }
}
/*
嘟嘟嘟~张三,18
嘟嘟嘟~李四,19
*/

可以理解位p1和p2各拿了一个雕像进行涂鸦,所以不会影响到彼此的内容

现在把p1赋值给p2,使p1和p2操作的是同一个雕像然后进行修改内容。

 public static void main(String[] args) {
        Person p1 =new Person();
        p1.name="张三";
        p1.age=18;
        p1.tell();

        Person p2 =p1;
        p2.age=19;
        p2.tell();
    }
/*
嘟嘟嘟~张三,18
嘟嘟嘟~张三,19
*/

从结果上看p2成功修改了p1的一部分涂鸦,让其沾上了自己的颜色!

上述栗子其实是所谓的引用传递

各拿一个雕像进行涂鸦的时候。其实就是堆内存中开辟了两个空间,然后栈内存中p1和p2各指向一个空间。
image

p2操作p1雕像的时候。其实就是堆内存中只开辟了一个空间,然后栈内存中的p1指向唯一的空间,p2也指向唯一的空间。所以会导致p2成功涂鸦p1的雕像
image

//有时候也会有特殊情况
        Person p2 = new Person();
        p2.name = "李四";
        p2.age = 19;
        p2 = p1;

原本p2好好的结果突然指向了p1的雕像,这就会导致p2原来的空间形成垃圾空间。

垃圾空间会等待Java本身提供的垃圾回收机制(GC)来释放空间。

因为一个栈内存空间只能指向一个堆内存空间。

封装性

面向对象的第一大特性,封装即包装好。使得外部不可见

在上面的栗子中Person类的成员属性可以被任意的访问并修改。封装就可以保护好类中的属性。

要封装属性或方法操作如下
private 数据类型 属性名;
private 返回值类型 方法名(传参){};

是的没错只需要在属性或方法前加上私有的访问修饰符即可封装。试一试

public class test2 {
    public static void main(String[] args) {
        Person p1 = new Person();
        p1.name = "张三";
        p1.age = 18;
        p1.tell();
    }
}

class Person {
    private String name;
    private int age;

    public void tell() {
        System.out.println("嘟嘟嘟~" + name + "," + age);
    }
}
//报错,甚至编译都无法通过,那么对象p1该怎么去访问属性呢?

在封装完毕的情况下,要怎么去访问属性或者方法呢?

为了解决属性必须封装又必须访问的矛盾,在Java开发中有明确的定义:

“只要是被封装的属性,必须通过getter和settter方法修改和访问”

加上getter和setter方法

public class test2 {
    public static void main(String[] args) {
        Person p1 = new Person();
        p1.setName("张三");//setter方法
        p1.setAge(18);
        p1.tell();

    }
}

//this关键字用于访问成员变量
class Person {
    private String name;//成员变量
    private int age;

    public void tell() {
        System.out.println("嘟嘟嘟~" + this.name + "," + this.age);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {//this.name为成员变量 name为局部变量
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
/*
嘟嘟嘟~张三,18
*/

另外this还可以访问本类中的方法

this.方法名(传参);

public class test2 {
    public static void main(String[] args) {
        Person p1 = new Person();
        p1.setName("张三");//setter方法
        p1.setAge(18);
        p1.tell();
		 p1.say();
    }
}

//this关键字用于访问本类中的方法
class Person {
    private String name;//成员变量
    private int age;

    public void tell() {
        System.out.println("嘟嘟嘟~" + this.name + "," + this.age);
    }

    public void say() {
        this.tell();
    }
	//getter和setter
}
/*
嘟嘟嘟~张三,18
嘟嘟嘟~张三,18
*/

需要实例化的对象一多,不可能我每个都去setter一下吧?构造方法由此诞生!

构造方法

构造方法主要作用是初始化类中的属性。

  • 构造方法必须和类名相同
  • 构造方法不能有任何返回值类型(包括void)
  • 构造方法不能有return语句。
构造方法格式如下
访问修饰符 构造方法名(传参){
//方法体
};

举个栗子

public class test2 {
    public static void main(String[] args) {
        Person p1 = new Person("张三",18);//调用构造方法进行对象(实例)初始化
        p1.say();
    }
}
class Person {
    private String name;
    private int age;

    public Person() {//无参构造方法
    }

    public Person(String name, int age) {//有参构造方法
        this.name = name;
        this.age = age;
    }
    public Person(String name) {//构造方法的重载
        this.name = name;
    }

    public void tell() {
        System.out.println("嘟嘟嘟~" + this.name + "," + this.age);
    }
	//getter和setter
/*
嘟嘟嘟~张三,18
*/

一类个中会默认生成一个什么都不做的无参构造方法。

    public Person() {}//默认生成的无参构造方法

其中,如果定义了有参的构造方法必须显性定义无参构造方法

posted @ 2023-10-15 22:23  rowbed  阅读(5)  评论(0编辑  收藏  举报