Java中的类和方法(方法重载)

2024-01-02 21:14:27

目录

前言:

什么是面向对象?

什么是类?

类和方法的关系:

方法的定义:

方法重载:

类的定义:

修改类的名字:

实例化:?

利用方法对其属性赋值:?

this关键字:?

this的意义:?

this的使用:

对象的构造以及初始化:?

非构造方法初始化:

构造方法:

this调用构造方法:

构造方法特性:

总结:


前言:

? ? ? ?Java的特色就是面向对象,对象的上面是什么?对,就是类,这一章,我们就来仔细讲一讲类。

什么是面向对象?

? ? ? ?什么叫面向对象?什么叫面向过程?(如果你只学过C语言,那么说你之前写的代码都是面向过程)其实这两个概念也不用一直去纠结。比如把大象装进冰箱。

?面向对象就会1.打开冰箱2.塞进大象3.关上冰箱。

?而面对过程1.如何打开冰箱?2.如何塞进大象?3.如何关上冰箱?

?? ? ? ?面向对象需要:找对象 创建对象 使用对象。

什么是类?

? ? ? ?这其实是一个抽象的概念,类似于C语言中的结构体。我们一般使用的都是基本数据类型(char、double、int之类的),但是定义一本书该怎么办?和C语言一样,需要自定义一种类型,之后一个具体的类叫做对象。

? ? ? ?打个比方,我们老师,同学,亲人等等,这些人。你会发现他们都是人,同属于一个类,这个类就是人。他们都有具体的一些属性:姓名,年龄等等。当这些属性有了具体的数据,比如:张三,18岁。这个张三就是一个具体的类了,可以把他称作为-对象。

? ? ? ?此时你就会理解什么是类了,类和对象的关系是什么。

类和方法的关系:

? ? ? ?我们知道每个人都是人类,都是人这个类的对象,那么人就都有一些共同的做法。比如吃饭,睡觉。

? ? ? ?动物也是类,都有睡觉,大叫的做法。

? ? ? ?我们把一个类的共同做法叫做方法,在类中定义,是一种所属关系。

方法的定义:

? ? ? ?定义方法和定义函数类似。

? ? ? ?有返回值就一定要返回。

? ? ? ?在Java中,方法必须在类里面,方法不能嵌套方法(不能嵌套定义)。在Java中没有方法声明这一说。

? ? ? ?Java方法也会开辟空间(就是方法的栈帧,这里详情请看函数的栈帧-CSDN博客)。

方法重载:

? ? ? ?Java中对方法有一种神奇的用法,会方便我们去调用方法。

? ? ? ?此时我们要求和,分别是対整数和浮点数进行求和,如果都写成方法,就要两种方法,因为类型不同。

public static int addInt(int a, int b){
    return a + b;
}
public static double addDouble(double a, double b){
    return a + b;
}

public static void main(String[] args) {
    int x = 10;
    int y = 20;
    int ret = addInt(x, y);
    System.out.println(ret);

    double d1 = 12.3;
    double d2 = 12.3;
    double sum = addDouble(d1, d2);
    System.out.println(sum);
}

? ? ? ?这种方式比较冗余,都是实现加法,但是要调用两种方法,所以就衍生出:方法重载。

? ? ? ?Java中允许存在相同名称的方法,但是要求返回值、参数列表不同。

? ? ? ?所以此时我们就可以将以上代码修改为:

public static int add(int a, int b){
    return a + b;
}

public static int add(int a, int b, int c){
    return a + b;
}
public static double add(double a, double b){
    return a + b;
}

public static void main(String[] args) {
    System.out.println(add(1, 3));
    System.out.println(add(1.7, 1.5));
    System.out.println(add(1, 2, 3));
}

所以Java中定义:?如果多个方法的名字相同,参数列表不同,则称这几种方法被重载了。

? ? ? ?那么java中到底如何区分呢?有一个东西叫做方法签名,就是经过编译器修改过之后方法最终的名字。

? ? ? ?所以完整方法名:方法路径名 + 参数列表 + 返回值类型。

? ? ? ?我们也可以看具体细节,先编译生成字节码class文件后,在控制台中进入到要查看的.class所在目录,输入:javap -v 字节码文件名字即可。

? ? ? ?我认为看到这里没几人会去实际操作吧,哥哥们。这个只是让你们看到具体的方法名,没必要去实操,但是还是肯定会有的,因为我给的步骤不全,可能有些人就划走了。

? ? ? ?所以我我给出具体步骤(这里我就不给出我写的另一个博客链接了,就这一点不跳转了),打开当前.java文件目录,在当前.java路径中输入cmd,之后先编译,输入javac 文件名.java,之后生成了字节码文件(.class文件)。

(上方是参考图,不是这个文件)之后按照那个输入即可。?

? ? ? ?最后的那个大写的符号就是返回值。

? ? ? ?这个了解即可。

类的定义:

? ? ? ?有了以上基础,我们就来看看类是如何定义的?

class ClassName{
    field; //字段(属性) 或者成员变量
    method; //行为 或者 成员方法
}

? ? ? ?类名注意采用大驼峰定义,成员前写法统一为public(以后会讲解),此处写方法不带static关键字(以后讲解)。

class Person{
    //属性  字段  成员变量 : 定义在类当中 方法外部的变量
    //public 访问修饰限定符
    public String name;
    public int age;

    //静态成员变量
    public static int count = 10;

    //方法   行为
    public void Sleep(){

    }

    //静态成员方法
    public static void staticMethod(){

    }
}

? ? ? ?这里面有两个分类:

? ? ? ?每一个类,?都会产生一个字节码文件(一般最好是这个类前面有public修饰,因为一个文件只能有一个public修饰的类),我们这里为了方便讲解,在一个文件中创建了多个类,一般建议一个文件中一个类。

? ? ? ?此时我们先执行以下代码:

class Person{
    //属性  字段  成员变量 : 定义在类当中 方法外部的变量
    //public 访问修饰限定符
    public String name;
    public int age;

    //静态成员变量
    public static int count = 10;

    //方法   行为
    public void Sleep(){

    }

    //静态成员方法
    public static void staticMethod(){

    }
}

//class ClassName{
//    field; //字段(属性) 或者成员变量
//    method; //行为 或者 成员方法
//}

public class test {
    public static void main(String[] args) {
        int a = 10;//局部变量
    }
}


class PetDog{
    public String name;//名字
    public String color;//颜色

    //狗的属性
    public void barks(){
        System.out.println(name + "汪汪");
    }
}

? ? ? ?之后在文件上右击选取explorer。

? ? ? ?并返回上一级目录点击out,进到最里面会发现生成了好几个class文件。?

? ? ? ?由此可得,一个类就会生成一个.class文件。?不建议一个文件中有多个类,建议一个类放在一个文件当中,这样好管理。
? ? ? ?public修饰的类必须要和文件名相同!而且main方法所在类一般要使用public修饰。

修改类的名字:

? ? ? ?因为我们建议一个文件中一个类,所以不能只通过修改类的名字来进行重命名,不能直接修改,要借助工具。比如我们修改test类的名称。

? ? ? ?但是这只针对一个文件中有一个类,当一个文件中有多个类,这样改就会报错。

实例化:?

? ? ? ?将类进行实例化,其实也就是创建了一个对象,但是这个对象的赋值一开始不能像C语言一样赋值。我们先往下看:

//实例化 -> 就是实例化一个真正的实体
PetDog dog1 = new PetDog();

//通过 new 可以实例化多个对象
PetDog dog2 = new PetDog();
PetDog dog3 = new PetDog();

? ? ? ?所以创建的对象也是引用变量。此时我们对其每一个成员变量进行赋值:

public class test {
    public static void main(String[] args) {
        //实例化 -> 就是实例化一个真正的实体
        PetDog dog1 = new PetDog();
        //赋值
        dog1.name = "lele";
        dog1.color = "black";

        System.out.println(dog1.name);
        dog1.barks();


        int a = 10;//局部变量
    }
}
class PetDog{
    public String name;//名字
    public String color;//颜色

    //狗的属性
    public void barks(){
        System.out.println(name + "汪汪");
    }
}

? ? ? ?使用.来访问对象中的属性和方法。?

? ? ? ?类里面的方法是在方法区存放的,我们以后详解。

利用方法对其属性赋值:?

? ? ? ?我们创建一个方法进行快速赋值:

public class Date {
    public int year;
    public int month;
    public int day;

    public void setDay(int y, int m, int d){
        //相当于一个方法
        year = y;
        month = m;
        day = d;
    }

    public static void main(String[] args) {
        Date date = new Date();
        //date.day = 11; 我们先不进行这样赋值
        date.setDay(1999,1,11);
        Date date1 = new Date();
        date1.setDay(1899,2,3);
    }
}

? ? ? ? 注意上面有两个对象创建成功了,都调用了一个方法,方法为了明确到底对谁进行赋值,我们知道是前面使用的对象调用的方法,所以其实有隐藏参数。

this关键字:?

this的意义:?

? ? ? ?所以为了更好的区分,我们在方法中使用属性,前面都加上this.

public void setDay(int y, int m, int d){
    //相当于一个方法
    this.year = y;
    this.month = m;
    this.day = d;
}

? ? ? ?我们先举一个例子:

public class Date {
    public int year;
    public int month;
    public int day;

    public void setDay(int year, int month, int day){
        //相当于一个方法
        year = year;
        month = month;
        day = day;
    }

    public void print(){
        System.out.println("year:" + year + "month:" + month + "day" + day);
    }

    public static void main(String[] args) {
        Date date = new Date();
        //date.day = 11; 我们先不进行这样赋值
        date.setDay(1999,1,11);
        date.print();
        Date date1 = new Date();
        date1.setDay(1899,2,3);
        date1.print();
    }
}

? ? ? ?结果为0是因为:?

? ? ? ?因为局部变量优先,所以要加上this,这样就能更好的区分。

public void setDay(int year, int month, int day){
    //相当于一个方法
    this.year = year;
    this.month = month;
    this.day = day;
}

? ? ? ?this只能引用当前对象,不能引用其他对象。所以我们要习惯使用this。方法里出现属性也要加上this。

public void print(){
    System.out.println("year:" + this.year + " month:" + this.month + " day" + this.day);
}

this的使用:

  • this.成员变量
  • this.成员方法

? ? ? ?this可以后面跟上成员变量,也可以跟上成员方法(就是当前对象调用了方法)。

class PetDog{
    public String name;//名字
    public String color;//颜色

    public void eat(){
        System.out.println(this.name + "吃饭");
    }
    //狗的属性
    public void barks(){
        this.eat();
        System.out.println(name + "汪汪");
    }
}

对象的构造以及初始化:?

非构造方法初始化:

? ? ? ?我们只能针对每一个属性进行初始化。

PetDog dog1 = new PetDog();
dog1.name = "xiaole";
dog1.color = "red";
//构造对象

? ? ? ??我们也可以进行另一种初始化(就地初始化)。

class PetDog{
    //就地初始化
    public String name = "lele";
    public String color = "red";

    public void eat(){
        System.out.println(this.name + "吃饭");
    }
    //狗的属性
    public void barks(){
        this.eat();
        System.out.println(name + "汪汪");
    }
}

public class day_12_27 {
    //静态成员方法
    public static void main(String[] args) {
        PetDog dog1 = new PetDog();
        
    }
}

? ? ? ?一般情况下有特殊业务需求才会使用。?也可以重新赋值,就好像修改变量一样。局部变量使用时一定要进行初始化,但是成员变量(属性)不初始化是默认赋值的。引用类型默认值都是null。

构造方法:

? ? ? ?构造方法:一个非常特殊的方法!没有返回值,方法名必须和类名是一样的,当然也需要使用this。

public Student(){
    //初始化成员变量
    this.name = "daniu";
    this.age = 9;
}

? ? ? ? 因为这个构造方法里面没有参数,所以我们称它为无参构造器。

?? ? ? ?但是我们之前没有使用过构造方法,是不是意味着构造方法可有可无?我们可以发现,我们没有去调用构造方法,但是它却将对象赋值初始化了,也就是说,构造方法是默认调用的。

? ? ? ?其实,对象产生时(实例化对象时),有两部很关键:为对象分配空间,调用合适的构造方法。?

? ? ? ?当我们没有写任何构造方法时,Java会提供一个默认构造方法。?

public Student(){
    
}

? ? ? ?如何验证,很简单,就是我们没有进行初始化时,默认都是0和null值。?

? ? ? ?所以没有构造方法时,编译器就默认帮你补上构造方法,写了就没有默认构造方法。我们刚才说,合适的构造方法,所以就存在多种构造方法。

class Student{
    public String name;
    public int age;

    //构造方法,接收参数
    public Student(String name, int age){
        this.name = name;
        this.age = age;
    }

    //构造方法
    public Student(){
        //初始化成员变量
        this.name = "daniu";
        this.age = 9;
    }
    
    public void show(){
        System.out.println("姓名:"+this.name+" 年龄:"+this.age);
    }
}

public class day_12_27 {
    public static void main(String[] args) {
        Student s = new Student();
        Student s1 = new Student("zhangsan", 9);
        //直接使用构造方法实例化对象
        s.show();
        s1.show();
    }
}

? ? ? ?所以构造方法之间构成重载关系。?此时我们把无参构造器删除。

? ? ? ?此时发现代码报错,但是编译器不是能自动提供一个无参构造器吗?但是此时有构造器了。如果你没有写构造器,就默认会有无参构造器。但一旦写了一个,无参构造器没就没了。?所以叫做救急不救穷。

? ? ? ?但是有多个成员变量时,我们写构造器就会有些麻烦,难道要把所有参数都写一遍吗?其实IDEA提供了快捷方式(Alt + Insert)或者鼠标右击点击generate,并把全部成员选中即可。

?? ? ? ?此时就快捷生成了构造器,生成时我们可以进行选择,生成有参还是无参的构造器。

this调用构造方法:

? ? ? ? this可以调用方法,那么构造方法也可被this调用,比如:

this("鼠标",9);

?? ? ? ? 这个语法只能出现在构造方法当中!

? ? ? ?不能自己调用自己(this();),且必须出现在当前构造方法的第一行,否则报错。?

? ? ? ?所以有些地方说this代表当前对象是不正确的。?

构造方法特性

? ? ? ?名字必须和类名相同,没没有返回值类型,设置void也不行。创建对象时编译器自动调用,并且在对象的生命周期内只调用一次。构造方法可以重载。我们也可以验证:

class Student{
    public String name;
    public int age;
    public Student() {
        //调用其他构造方法 -> 只能在构造方法中写
        this("鼠标",9);
        System.out.println("gaga");
    }
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("haha");
    }
    public void show(){
        System.out.println("姓名:"+this.name+" 年龄:"+this.age);
    }
}
public class day_12_27 {
    public static void main(String[] args) {
        Student s1 = new Student();
        s1.show();
    }
}

? ? ? ? 这里一定要注意,不能形成环。

public Date(){
    this(19,1,1);
}

public Date(int y,int m, int d){
    this();
}

总结:

? ? ? ?成员属性/成员变量:定义在方法外部,类内部的变量。

文章来源:https://blog.csdn.net/weixin_64132124/article/details/135339827
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。