像我们搞计算机这块的,都知道这么一件事,当前的计算机编程语言主要分为两大块,一为面向过程,二为面向对象。Java就是一门纯面向对象的语言。学习了一个月左右的Java,在下对于Java当中的类和对象有了基本的认识。接下来我就来谈谈自己的看法,各位大神勿喷,新手小白敬上。
既然谈到类和对象,首先,我们要明确一个概念。那就是,什么叫类?什么是对象?
首先让我们来谈谈什么叫类。类是一个比较抽象的概念,如何给它定义,是一个难题。我们通常这样称呼它,模板。是的,它代表了具有相同属性、行为等的一种事物。就比如,凳子、桌子、电脑、人。这里,我们并不是指定某一个具体的东西,而是这类事物的总称。而Java中的类,其实就是这样的泛指。那么什么是对象呢。比如,这台电脑,这个人,这张桌子。类和对象有着密不可分的关系。类,是一些具有相同属性行为的对象的通用模板。对象,是一个类的实例化的产物。能够区分什么是类,什么是对象,这是学习Java以及所有面向对象的编程语言的第一步,也是非常关键的一步。
认识了类和对象之后,接下来,我们要弄清楚Java当中定义类和对象的格式。
如何定义一个类?一个类,它要包括哪些方面的内容?我们就拿人来说吧。人,头、眼镜、鼻子、嘴。这些,就是人这个类的特征。在Java里面,我们通常称之为属性。而除了这些内容,我们还知道,人会思考,要吃饭睡觉。这些,是人产生的行为。在Java里面,我们称之为方法。而一个类,通常就是由属性和方法两部分组成的。换句话说,定义一个类,我们就要阐明类的属性和方法这两部分。定义一个类的格式一般为,public class 类名{}。花括弧里面就是我们要填充的类的属性和方法。定义属性的一般格式为 访问修饰符 数据类型 属性名。定义方法的一般格式为 访问修饰符 返回值类型 方法名(参数类型 参数名)。事实上,方法括号里没有参数也是可以的。
接下来,我们来实现一个类的定义以便更好地理解。我们不妨来定义一个学生类Student。学生类的属性,有姓名、年龄、学号以及学分,学生类的方法,有学习、玩耍。具体实现如下:
在这段程序中,我特意用上了所有的访问修饰符。可以注意到,定义每个属性的访问修饰符都是不一样的。在Java当中,一共有四种访问修饰符,比我们熟知的C++要多一种。四种访问修饰符分别为:public,protected,默认,private。四种访问修饰符的排列顺序,即为其访问权限由大到小的排列顺序。从public开始讲,public的访问权限最大,被public修饰的成员,可以在任何一个类中被调用,不管同包或不同包,是权限最大的一个修饰符。接下来是protected。被protected修饰的成员,能在定义它们的类中,同包的类中被调用。而如果想要在不同包的另一个类中调用,那么要求这个类为成员所在类的子类。即在存在继承关系的情况下,被protected修饰的成员可以在不同类中被调用。被默认的修饰符修饰的成员,也能在同类、同包当中被调用,但是,即便存在继承关系,它也不存在跨包调用。private作为最严苛的修饰符,被它修饰的成员,只能在当前类之中才能被调用,而如果想要调用私有量,就必须借助公有的方法来传递这个私有量。举个例子,当类中的name属性为私有量,我们可以定义一个public String setName()的公有方法,利用它返回这个name属性。在这个类当中,除了属性,我们看到还有两个方法,Study和Play。我们注意到,方法的访问修饰符一般为public。事实上,方法的访问修饰符是可以为其他类型的。但是,作为一个类在外部的作用的具体实现,在外部如果不能调用,那么这个类与外部的连接也就断了,那么它的意义也就失去了。除此之外,两者的返回值类型也不相同,注意当返回值类型不为空的时候,需要返回一个类型相同的值。再者,如果在这个方法里面,你需要使用到外界的数据,可以将其以参数的形式传递到这个方法里面来。如果不需要,那么参数可以为空。
这样,一个类就定义好了。接下来我们要做的,就是实例化一个对象出来。对象实例化的关键词是new,实例化对象的格式是 类名 对象名=new 类名()。事实上,这种说法其实并不准确。具体将在后文当中提到。接下来,我们将实例化一个Stu并赋初值:
可以看到,我们实例化了一个Stu,并给它赋了相应的初值,进行了一系列的行为。
让我们把目光集中到Student Stu=new Student();这一行代码上,我们刚才说过,这是实例化对象的基本格式 类名 对象名=new 类名(),刚才我们也说过,这种说法其实并不准确。正确的说法应该是,实例化对象的格式为 类名 对象名=new 构造方法名()。那么,问题来了,什么是构造方法?首先,构造方法是一个方法。但是它与其他普通方法并不相同,它是一种特别的方法。它的作用在于,实例化对象,甚至在其有参数的情况下,可以实现给对象的一些属性赋初值。那么,如何定义一个构造方法呢?定义构造方法的基本格式为 public 类名(参数类型 参数名)。我们注意到,这与定义普通方法的格式略有区别。注意,定义构造方法是不需要加返回值类型的,再者,方法名必须为类名,而不能像定义普通方法只需满足命名规则就好。接下来,我们要谈到与构造方法有关的几点。(1)相信细心的朋友已经发现了,在类中,我并没有定义构造方法,然而实例化对象的时候并没有报错。因为,在定义类的时候,如果你没有自行定义构造方法,那么系统会给你一个默认的构造方法,仅可用于实例化对象。(2)如果你在类中自行定义了构造方法,那么系统将不会提供构造方法或者说系统提供的构造方法被定义的构造方法覆盖。(3)一个类可以定义多个构造方法。(4)构造方法每调用一次,一定会创建一个新的对象。我们继续看回到实例化对象的这行代码。事实上,Java把内存分成两种,一种叫做栈内存,一种叫做堆内存。在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配。当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间,当超过变量的作用域后,java会自动释放掉为该变量分配的内存空间,该内存空间可以立刻被另作他用。堆内存一般用作存放由new 创建的对象和数组。而在这行代码当中,Student Stu作用是在栈内存中开辟一个内存空间储存Stu这个对象名。而new在堆内存中开辟的内存空间则储存了Student类里面的属性和方法。两者之间由等号进行关联。等号的作用在于,将储存Student属性和方法的内存地址作为信息传递给栈内存Stu所在地并且保存下来。这就是构造方法实现实例化对象的具体过程。我们不妨来看个构造方法的例子加强理解:
在这段代码当中,我们可以看到在这个类当中的两个构造方法的不同形式。
接下来,我想谈谈类和对象与Java当中另一个知识点this结合在一起的用法。我们都知道,C++里有this指针,Java是废除了指针的,Java中的this其实与this指针的功能上有点类似。我们不妨来看看下面这段代码:
运行结果如下:
事实上,this除了调用成员变量以及成员函数,还可以用来调用构造方法。它能根据所含参数的类型,自动选择符合的构造方法。这里展开一点拓展,如果有两个类存在继承关系,那么在子类实例化对象的时候,需要调用到父类的构造方法,这就需要用到super,用法与this类似。关于这点,会在以后的博客里详解。
讲了这么多,我相信,看到这篇博客的诸位应该对类和对象的知识有了基本的了解。事实上,类和对象的知识远不止如此,我讲的只是皮毛。如果有哪些常识性的错误,请各位大神大方指出来,新人好改,以免误人子弟。最后,希望这篇博客最好能给大家带来一些启发,能帮助一些对这个知识点一无所知的人了解Java里的类与对象。新人小白敬上。