JAVA快速入门-类的引入

版权声明:欢迎转载,转载请注明出处 http://blog.csdn.net/itdo_just https://blog.csdn.net/itdo_just/article/details/79313679

这章主要描述 JAVA 的类,类(Class)是面向对象程序设计(OOP,Object-Oriented Programming)实现信息封装的基础。类是一种用户定义类型,也称类类型。每个类包含数据说明和一组操作数据或传递消息的函数。类的实例称为对象。


实际上 C 语言里面的结构体就跟类非常的相似,下面先以一个 C 语言的例子来实现面向对象程序设计的思想,然后用此例子来说明它存在的一些缺陷,在面向对象这方面 JAVA 做的更好。程序如下:

#include <stdio.h>

/* oop思想:把人构造为结构体,在结构体内构造属性及操作函数 */
struct person {
    char *name;
    void (*printName)(struct person *per);
};

/* 如果结构体很庞大,用整个结构体做参数很没效率,可以传指针 */
void printName(struct person *per)
{
    /* 如果还想打印其它的,只需要修改这个函数就可以对应上所有的结构体 */
    printf("guangdong %s\n",per->name);
}

int main(void)
{
    struct person p1 = {"zhangsan", printName};
    struct person p2 = {"lisi", printName};

    p1.printName(&p1);
    p2.printName(&p2);
}

这个程序实现功能上是完全没有任何问题的,但是有些地方特别别扭,又显示麻烦,像我们的结构体内部定义了一个函数指针,却不能直接实现功能要跑到外面去实体化函数指针,再者后面的“打印名字”那个函数指针的调用“p1.printName(&p1);”这句前面明明说明了是p1,但是后面你想打印的时候你又要获取多一次p1的地址,这样程序看起来感觉有点多余和冗余,但是没办法,这就是C语言。因此,我们能否改进呢?答案是当然可以,使用JAVA,具体实现我们先看代码,如下:

class Person{
    String name;
    String getName(){
        /* 为什么可以直接使用'+'号,因为这两个参数同为String类 */
        /* 而'+'号被重载过,判断到有两个String类参数相加则合并到一起 */
        /* JAVA的优势体现,我们可以直接在这里实体化函数内容,这里称为实体化方法 */
        return "guangdong" + name;
    }
}

public class Oop{
    public static void main(String args[]){
        /* 类是引用数据类型,所以都要 new */
        Person p1 = new Person();
        p1.name = "zhangsan";

        Person p2 new Person();
        p2.name = "lisi";

        System.out.println(p1.getName());
        System.out.println(p2.getName());
    }
}

从上面这段JAVA的代码我们可以明显看出来比前面那段C的代码要简短明了很多,这就是JAVA程序的好处,他可以让代码和对象更加紧凑,直接在类里面实体化对象,使人这个对象的描述能力更加强,这也是面向“对象”的语言的优势。下面继续完善上面的 JAVA 程序,上面定义了一个类对象之后对其成员变量进行赋值,但这样显得非常麻烦,在 JAVA 里面我们可以使用构造方法,即在构造这个对象的时候就自动执行同名的成员方法,还是以程序来说明比较直观,如下:

class Person{
    String name;
    String getName(){
        return "guangdong " + name;
    }

    /* 构造方法:构造这个对象的时候,系统会来自动执行这个函数 */
    public Person(String n){
        name = n;
    }
}

/* public:公共类,在同一个文件里面只能有一个public class,其它class不能加 */
public class Oop2{
    public static void main(String args[]){
        Person p1 = new Person("zhangsan");     
        Person p2 = new Person("lisi");

        System.out.println(p1.getName());
        System.out.println(p2.getName());
    }
}

这段代码只用一行就替代了上面的两行代码,更加简洁了,那可能会有另一个问题,就是人这个对象怎么可能只有名字呢,他还有一些其它的参数如何通过构造函数来赋值呢,可以使用重载,重载构造方法即可,重载实际上就是指重新给对象一个新的定义,让它可以根据情况身兼多职,比如如下代码它的构造方法的实参可以不同,然后根据不同的实参来调用不同的构造方法。

class Person{
    String name;
    int age;
    String getName(){
        return "guangdong"+" name "+name+" age "+age;
    }

    /* 重载构造方法 */
    /* Construct method */
    /* 构造方法:构造这个对象的时候,系统会来自动执行这个同名方法 */
    public Person(){
        name = "null";
        age = 0;
    }
    /* this表示当前对象或当前类,没有用this指示即就近原则 */
    /* 名字一样的情况不使用 this 就无法区分哪个是这个类的,哪个是形参的 */
    public Person(String name){
        this.name = name;
    }

    public Person(String name, int age){
        this.name = name;
        this.age = age;
    }
}

/* public:公共类,在同一个文件里面只能有一个public class,其它class不能加 */
public class Oop3{
    public static void main(String args[]){
        /* 重载构造方法:下面的实例会根据形参调用不同的同名构造方法 */
        Person p1 = new Person("zhangsan");
        Person p2 = new Person("lisi");
        Person p3 = new Person();
        Person p4 = new Person("wangwu",6);

        System.out.println(p1.getName());
        System.out.println(p2.getName());
        System.out.println(p3.getName());
        System.out.println(p4.getName());
    }
}

接下来如果还需要统计一下目前总共实例化了多少个对象怎么做呢,可以直接在每个构造函数里面对一个成员变量 count 进行“++”操作,下面用代码来描述下。

class Person{
    ...
    /* 类属性:加了static关键字的在java里面叫“类属性” */
    /* count 在构造函数里面可以用来表示总人数的多少,
       加了static表示这个类本身的属性,不属于某个实例 */
    static int count;
    public Person(){
        count++;
    }
    public Person(String name){
        count++;
    }
    public Person(String name, int age){
        count++;
    }   
    /* 加了static即“类方法”,它不需要new,不需要具体的对象实例化 */
    static void printPerson(){
        System.out.println("This is a class of Person");
    }
}
public class Oop{
    public static void main(String args[]){
        /* 类属性和类方法都不需要实例化即可以直接使用 */
        ....
        Person.printPerson();
        System.out.println(Person.count);
    }
}

上面的 count 的操作方式确实可以,但是如果有很多个重载的构造函数每个都要做这步操作就太冗余也太麻烦了,JAVA做的非常完善,为此它还提供了构造块和静态块,下面完整代码的实现,有备注说明构造代码块和静态代码块的作用。

class Person{
    String name;
    int age;
    String getName(){
        return "guangdong"+" name "+name+" age "+age;
    }

    /* 类属性 */
    static int count;//在构造函数里面加可以用来表示总人数的多少,加了static表示这个类本身的属性,不属于某个实例

    /* 静态块:实例化一个对象的时候执行,且只执行一次*/
    static{
        System.out.println("static block");
    }

    /* 先执行构造块,再执行构造方法 */
    /* 构造块:不同于构造方法,每次实例化一个新对象的时候构造块都会被调用 */
    {
        /* 由于每次实例化一个对象就被调用一次,所以count放这里++最合适 */
        System.out.println("construct block");
        count++;
    }

    /* Construct method */
    /* 构造方法:构造这个对象的时候,系统会来自动执行这个函数 */
    public Person(){
        System.out.println("construct block 1");
        name = "null";
        age = 0;
    }
    public Person(String name){
        System.out.println("construct block 2");
        this.name = name;//this表示当前对象或当前类,没有指示即就近原则
    }
    public Person(String name, int age){
        this.name = name;
        this.age = age;
    }

    /* 加了static即类方法,就不需要new,不需要具体的对象实例化 */
    static void printPerson(){
        System.out.println("construct block 3");
        System.out.println("This is a class of Person");
    }
}

/* public:公共类,在同一个文件里面只能有一个public class,其它class不能加 */
public class Oop5{
    /* main前面有static就表示这属于类方法 
       java虚拟机执行这个程序的时候就不需要去构造Oop5的对象 */
    public static void main(String args[]){
        Person p1 = new Person("zhangsan");
        Person p2 = new Person("lisi");
        Person p3 = new Person();
        Person p4 = new Person("wangwu",6);


        Person.printPerson();
        System.out.println(Person.count);
    }
}

最后以思维导图对以上内容做个总结
这里写图片描述

猜你喜欢

转载自blog.csdn.net/itdo_just/article/details/79313679