类和对象
在面向对象中,类和对象是最基本、最重要的组成单元。类实际上就是某类群体的一些基本特征抽象。对象就是表示一个个具体的东西。例如:做月饼时所使用的的模子就像是一个类,通过这个模子而做出来的一个个月饼就是对象。
1.类和对象的使用
类就是一类对象的统称。对象就是这一类具体化的一个实例。类是由属性和方法组成的。类的定义语法如下:
class 类名称{
数据类型 属性;
......
访问控制权限(public)返回值的数据类型 方法名称 (参数1,参数2 ...){
程序语句;
[return 表达式;]
}
}
根据以上格式就可以定义一个Person类。
class Person{
String name;
public void tell(){
System.out.println("他在说话");
}
}
在上面已经创建好了一个Person类,要想使用一个类就必须有对象。下面是对象的两种创建格式:
类名 对象名称 = null; //声明对象
对象名称 = new 类名(); //实例化对象
------------------------------
类名 对象名称 = new 类名();
下面便是创建对象的具体实例:
class Person{
String name;
public void tell(){
System.out.println("他在说话");
}
}
public class ClassDemo01{
public static void main(String[] args){
Person person = new Person(); //创建并实例化对象
person.tell();
}
}
-------------------------------
输出结果:
他在说话
以上程序在主方法中实例化了一个Person对象,对象的名称为person,与前面的数组开辟空间一样,对象的实例化也要划分堆、栈空间,具体内容如下图所示:
2.类的成员
类的成员可以包含以下:字段、方法、代码块、内部类以及接口。
2.1字段(field)
在类当中,但是于方法外部定义的变量。用于描述一个类当中包含哪些数据。
class Field{
//实例成员变量,存储在堆上
public String name;
//静态成员变量 ,存储在方法区内
public static int count = 10;
public static final int SIZE = 20;
// 实例成员变量 在堆上
public final int CAP = 30;
}
字段的默认值规则:对于各种数字类型,默认值为零值;对于boolean类型来说为false;对于引用类型(String,Array,以及自定制类),默认值为null。
字段使用 . 访问对象的字段,既能读也能写。若为显示设置初始值,均为默认值。
2.2 方法(method)
用于描述一个对象的行为。
class Paint{
public void paint(){
System.out.prinln("画画");
}
}
public class ClassDemo02{
public staic void main(String[] args){
Paint p = new Paint();
p.paint();
}
}
此处的paint方法就表示了Paint这个对象具有一个自我的行为。
方法当中还有一种特殊的方法为构造方法,使用关键字new实例化对象的时候会被自动调用,用于完成初始化操作。
一个对象的产生分为两个步骤:
1. 为对象分配内存,通过new关键字来实现;
2.调用合适的构造方法。
当类中没有提供任何的构造方法时,那么编译器会自动默认生成一个不带参数的构造函数,若类中已经有了构造函数那么默认的无参构造将不再生成。构造方法也支持重载。
在构造方法中,会出现this关键字这代表的是当前对象的引用,可以借助this来访问对象的字段和方法。在静态方法当中不能使用this关键字。
class Person {
private String name;//实例成员变量
private int age;
private String sex;
//默认构造函数 构造对象
public Person() {
//this调用构造函数
this("bit", 12, "man");//必须放在第一行进行显示
}
//这两个构造函数之间的关系为重载。
public Person(String name,int age,String sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
public void show() {
System.out.println("name: "+name+" age: "+age+" sex: "+sex);
}
}
public class Main{
public static void main(String[] args) {
Person person = new Person();//调用不带参数的构造函数
person.show();
}
}
构造方法也能发生重载,并且构造方法在单例模式下就能够变为私有的。
2.3 static关键字
static能够修饰属性、方法、代码块以及类。所有被static修饰之后,在调用时推荐使用类名来调用,因为其根本不需要对象的产生来支持 。
在修饰属性之后,其为静态成员变量,存储在方法区内。即同一个类当中的不同实例共用同一个静态属性。
static修饰方法,该方法将被称之为静态方法。静态方法属于类,而不属于类的对象。在没有类的实例前提下,依旧能够直接调用静态方法。
3.封装
封装性是面向对象的第一大特性,所谓封装性就是指对外部不可见。
封装的本质就是让类的实现着不必过多理解类的实现者是如何实现类的,只要知道如何使用类就可以了。这样能够降低类使用者的学习和使用成本。
3.1private 实现封装
被private 修饰的成员变量或成员方法,都不能被类的调用者所使用。
如果直接使用public修饰成员变量。
class Person {
public String name = "张三";
public int age = 18;
}
class Test {
public static void main(String[] args) {
Person person = new Person();
System.out.println("我叫" + person.name + ", 今年" + person.age + "岁");
}
}
-------------------------
输出结果:
我叫张三, 今年18岁
- 这样的代码导致类的使用者(main方法的代码)必须要了解 Person 类内部的实现, 才能够使用这个类. 学习成本较高。
- 一旦类的实现者修改了代码(例如把 name 改成 myName), 那么类的使用者就需要大规模的修改自己的代码, 维护成本较高。
要是使用private封装属性,并提供public方法供类的调用者使用。
class Person {
private String name = "小华";
private int age = 18;
public void show() {
System.out.println("我叫" + name + ", 今年" + age + "岁");
}
}
class Test {
public static void main(String[] args) {
Person person = new Person();
person.show();
}
}
-------------------------------------------
输出结果:
我叫小华,今天18岁
- 此时字段已经使用 private 来修饰. 类的调用者(main方法中)不能直接使用. 而需要借助 show 方法. 此时类的使用者就不必了解 Person 类的实现细节。
- 同时如果类的实现者修改了字段的名字, 类的调用者不需要做出任何修改(类的调用者根本访问不到 name, age这样的字段)。
private 不光能够修饰字段,也能修饰方法。通常将字段设置为private 属性,但是方法是否需要视情况而定,并不能无脑设置为public的。
3.2 获取与修改private修饰的属性
getter 和 setter 方法
class Person {
private String name;//实例成员变量
private int age;
public void setName(String name){
this.name = name;//this引用,表示调用该方法的对象
}
public String getName(){
return name;
}
public void show(){
System.out.println("name: "+name+" age: "+age);
}
}
public static void main(String[] args) {
Person person = new Person();
person.setName("caocao");
String name = person.getName();
System.out.println(name);
person.show();
}
4.匿名对象
匿名只是没有名字的对象。
- 没有引用的对象称为匿名对象。
- 匿名对象只能在创建对象时使用。
- 如果一个对象只是用一次, 后面不需要用了, 可以考虑使用。
class Person{
private String name;
private int age;
public Person(String name,int age){
this.name = name;
this.age = age;
}
public void show() {
System.out.println("name:"+name+" " + "age:"+age);
}
}
public class ClassDemo03{
public static void main(String[] args) {
new Person("xian",19).show();//通过匿名对象调用方法
}
}