万事万物皆对象,面向对象的编程就是对现实世界的模拟。
类和对象
人类的发展,先是有对象,随着社会的发展文明的进步,才有了类的概念。为了更好地认识世界,分门别类。
在编程世界,先是有类,再根据类创建出对象。类是对象的高度抽象,就是模拟。
类里面只有属性和方法。属性原本是对象的特征,方法原本是对象具有的功能。
举个例子:张三是一个人,他有姓名和年龄,会读书,写字。我们该如何抽象他?
第一步:他是人,所在我们可以定义类的名字为Person。class Person {}
第二步:他有属性:姓名和年龄,所以我们定义类的属性。String name;int age;
第三步:他有功能:读书和写字。所以有们定义类的方法。public void read(){} public void write(){}
由此完成了对张三的抽象。抽象的过程是编程的核心思想,需要多加训练。
由上可知,定义属性其实就是定义变量的过程。只有11种。要注意:类也是一种数据类型。
以前我们学的String类,Scanner类,Random类是JDK自带的,而今天我们是自定义类,也相当于自定了数据类型。
根据引用数类型使用,是需要四个步骤的,这个也不例外。我们写另外一个测试类叫TestPerson,里面有main方法。
第一步:声明变量 Person person;
第二步:分配内存 person = new Person();
第三步:赋值(用.运算符,它也叫成员运算符)
person.name = "张三";
person.age = 18;
第四步:使用,包含使用属性,使用方法。
person.read();
person.write();
System.out.println("姓名:"+person.name);
System.out.println("年龄:"+person.age);
跑起来。是不是非常简单呢?
以上的代码会有一个问题:我们可以为年龄赋值,但不能保证在具体的范围之内,如果我们如下:
person.age = 500;显然,这个不符合人类最长寿命,假设我们规定年龄必须介于18~25之间,那怎么处理呢?
在Java中,信息隐藏对于数据的安全性起到了一定作用,遇到上面的这种问题,如下处理:
先将age属性定义为私有的,private,这样其它类就不能直接为它赋值了。private int age;
于是我们提供set/get方法,那怎么写呢?
public void setAge(int age) {
if( !(age >= 18 && age <= 25)) {
System.out.println("年龄必须介于18~25之间");
return;
}
this.age = age;
}
public int getAge() {
return age;
}
通过上面的操作,就实现了信息的保护,用公有的方法访问私有的属性就实现了封装。
其实简单来说,方法里面可以写许多逻辑判断,而属性不能写,就意味着我们不能做过多的处理,具有局限性,这也是一种通用写法。就是当你写了一个类,里面的属性是私有的,那么就必须提供公有的set/get方法让外界访问。
我们的测试类会报错。person.age报错,因为私有的属性不能被外界直接访问,我们可以通过set/get方法来访问。
person.setAge(18);取代person.age = 18;
System.out.println(person.getAge());取代System.out.println(person.age);
构造方法
构造方法在哪里,我们见过吗?
当然见过,构造方法只能由new关键字调用。我们学过Scanner input = new Scanner(System.in);
我们学过Person person = new Person();
由此可见,构造方法和类名是一致的,代表的是构建这个类的对象,也叫创建类的实例。
那我们以前没写过呀!是的,没有写,但是类会提供一个默认无参的构造方法,看不见却存在的。那我们可以写吗?当然可以!
在上面的例子中,我们在Person类中添加
public Person() {
}
这就是一个无参的构造方法,既然写了,我们做点事情吧,在里面输出一句话。
public Person() {
System.out.println("这是无参的构造方法");
}
我们在测试类添加一句代码:
Person p2 = new Person();
再运行起来,你会发现控制台输出了 "这是无参的构造方法",这说明了什么?说明了无参构造的确是通过new Person()得到了执行呀,也可以说明构造方法是通过new关键字调用的。如果我们将构造方法写成如下:
public void Person() {
System.out.println("这是无参的构造方法");
}
这就不会输出那句“这是无参的构造方法”,因为系统认为它是一个普通方法。
所以,构造方法有其特性,第一要和类名一致,第二不能有返回类型void或其它11种数据类型,人家很干净,前面最多只有访问修饰符而已,切记!!!
上面我们写了无参的构造方法,那也就是说可以有有参的构造方法。那有参的构造方法又有什么作用呢?一般是这样的:
我们可以先创建对象,然后为每个属性赋值。
我们也可以在创建对象的时候,同时为每个属性赋值。
以上两种情况,在不同的场合都会发挥实际的作用。
我们写一个带参的构造方法:
public Person(String name,int age) {
this.name = name;
this.age = age;
}
以上代码中:this.age代表的是成员属性,name代表的是传进来的值,意思是将传进来的值赋值给对应的成员变量,达到了赋值的目的。
在main方法中怎么用呢:
Person p3 = new Person("李四",20);
这样就可以了,当李四的年龄如果想修改,我们就如下操作:
p3.setAge(19);而不用再创建对象了。
这样,构造方法赋值和set赋值各有各的用处,小伙伴们,体会到了吗?
这里还要注意一件事情,默认情况下,我们不写无参构造,它是存在的,但是,当我们写了有参的构造,那个隐藏的无参就会被取代,为了安全起见,我们会把无参的显示的写出来,而不是去偷懒,不写它。切记。
说了这么多,再来教一个小技巧吧。我们写好了一个类,想看它的图形效果,可以进行如下操作。
在类名上右击:
嘻: