面向对象
介绍
面向对象三大特征:
-
封装
-
继承
-
多态
一个类里面能写五类东西:
-
成员变量(代表属性,一般是名词)
-
成员方法(代表行为,一般是动词)
-
构造方法
-
代码块
-
内部类
类分为三种:
-
JavaBean 类
-
测试类
-
工具类
类名采用大驼峰命名规则。
一个 Java 源文件可以写多个类(实际开发不会这么做,实际开发中一般一个源文件只写一个类),但是最多只能有一个 public 类,如果有一个 public 类,则该 public 类的类名必须和文件名相同。
用来描述某一个事物的类称为 Javabean 类,Javabean 类中不写 main() 方法,可以写成员变量和成员方法,其中所有的成员变量都必须是私有的,同时提供对应的公有的 getter() 和 setter() 方法。除了 getter() 和 setter() 方法,如果 JavaBean 类中还有其他成员方法,也需要一并写出。
访问修饰符(access modifier)用于控制程序的其他部分对其所修饰部分的访问权限。
private 访问修饰符和 public 访问修饰符都可以修饰成员,例如成员变量和成员方法等,用 private 修饰的成员只能在本类中访问,用 public 修饰的成员可以在所有类中访问。
用 public 或 private 修饰成员变量时不影响它的默认值。
带 main() 方法的类称为测试类,可以在测试类中创建 Javabean 类的对象并赋值调用。
工具类只提供一些功能用来做某件事,所以也不会定义 main() 方法,为了方便调用,工具类中的方法都是静态的,即用 static 修饰的,这样就不需要定义对象,直接使用类名来调用。比如 Math 类:
public class Test {
public static void main(String[] args) {
int myAbs = Math.abs(-10);
System.out.println(myAbs); // 10
}
}
程序示例:
先写一个 JavaBean 类,再写一个这个 JavaBean 类的测试类。
JavaBean 类:
public class Phone {
private int price;
private String branch;
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public String getBranch() {
return branch;
}
public void setBranch(String branch) {
this.branch = branch;
}
// 其他成员方法
public void call() {
System.out.println("手机可以用来打电话。");
}
}
测试类:
public class PhoneTest {
public static void main(String[] args) {
Phone phone = new Phone();
phone.setBranch("苹果");
phone.setPrice(1000);
System.out.println("品牌为:" + phone.getBranch());
System.out.println("价格为:" + phone.getPrice());
// 调用其他成员方法
phone.call();
}
}
测试类的执行结果:
品牌为:苹果
价格为:1000
手机可以用来打电话。
在 JavaBean 类中定义成员变量时,一般都不会给成员变量赋一个初始值,因为各个对象的成员变量的值都可能不相等,而且当不给成员变量赋初始值时,成员变量会有一个默认值。
默认值:
-
基本数据类型:
-
byte、short、int、long:0
-
float、double:0.0
-
char:空格
-
boolean:false
-
-
引用类型:
- String、类、接口、数组:null
程序示例:
JavaBean 类:
public class DefaultValue {
private byte b;
private short s;
private int i;
private long L;
private char c;
private boolean boo;
private float f;
private double d;
private String st;
public byte getB() {
return b;
}
public void setB(byte b) {
this.b = b;
}
public short getS() {
return s;
}
public void setS(short s) {
this.s = s;
}
public int getI() {
return i;
}
public void setI(int i) {
this.i = i;
}
public long getL() {
return L;
}
public void setL(long l) {
L = l;
}
public char getC() {
return c;
}
public void setC(char c) {
this.c = c;
}
public boolean getBoo() {
return boo;
}
public void setBoo(boolean boo) {
this.boo = boo;
}
public float getF() {
return f;
}
public void setF(float f) {
this.f = f;
}
public double getD() {
return d;
}
public void setD(double d) {
this.d = d;
}
public String getSt() {
return st;
}
public void setSt(String st) {
this.st = st;
}
}
测试类:
public class DefaultValueTest {
public static void main(String[] args) {
DefaultValue defaultValue = new DefaultValue();
System.out.println(defaultValue.getB());
System.out.println(defaultValue.getS());
System.out.println(defaultValue.getI());
System.out.println(defaultValue.getL());
System.out.println(defaultValue.getC());
System.out.println(defaultValue.getBoo());
System.out.println(defaultValue.getF());
System.out.println(defaultValue.getD());
System.out.println(defaultValue.getSt());
}
}
测试类执行结果:
0
0
0
0
false
0.0
0.0
null
封装
Javabean 类的成员变量被定义为了私有, 即被 private 修饰, 同时提供对应的公有的 getter() 和 setter() 方法。外界对成员变量的操作 (包括赋值和获取值等等) 都应该通过 getter() 和 setter() 方法进行,而不是直接操作这些私有的成员变量。这便是封装。
this
this 的作用
定义在方法里面的变量叫做局部变量(包括定义在方法头内的形参变量),定义在方法外(当然,一定是在类里面)的变量叫做成员变量。
如果局部变量和成员变量同名,则在方法内局部变量覆盖成员变量,这叫做遵循就近原则。
如果不希望让局部变量覆盖成员变量,即希望在方法中可以访问到与局部变量同名的成员变量,就需要在访问成员变量时在成员变量前面加上关键字 this。
this 的作用:区分成员变量和局部变量。
this 的本质:代表了调用者(即某一个对象)的地址值。
this 的内存原理
程序示例:
JavaBean 类:
public class Student {
private int age;
public void method() {
int age = 10;
System.out.println(age);
System.out.println(this.age);
}
}
测试类:
public class StudentTest {
public static void main(String[] args) {
Student student = new Student();
student.method();
}
}
上述程序的内存原理:
程序示例:
JavaBean 类:
public class Girl {
private int age;// 成员变量
public int getAge() {
return age; // 返回成员变量
}
public int getAgeCovered() {
int age = 18; // 局部变量
return age; // 遵循就近原则,返回局部变量
}
public int getAgeNoCovered() {
int age = 18; // 局部变量
return this.age; // 返回成员变量
}
}
测试类:
public class GirlTest {
public static void main(String[] args) {
Girl girl = new Girl();
int ageCovered = girl.getAgeCovered();
int ageNoCovered = girl.getAgeNoCovered();
System.out.println("被覆盖:" + ageCovered);
System.out.println("没有被覆盖:" + ageNoCovered);
}
}
测试类执行结果:
被覆盖:18
没有被覆盖:0
程序示例:
JavaBean 类:
public class Boy {
private String name;
public String getName() {
return name;
}
public void setName(String n) {
name = n; // 如果成员变量和局部变量不同名,则 this 写或不写效果都一样,都是访问成员变量
}
public void setNameCovered(String name) {
name = name; // 等号左侧实际访问的是形参 name,所以没有对成员变量 name 进行赋值
}
public void setNameNoCovered(String name) {
this.name = name; // 等号左侧实际访问的是成员变量 name
}
}
测试类:
public class BoyTest {
public static void main(String[] args) {
Boy boy = new Boy();
System.out.println(boy.getName());
boy.setNameCovered("小明");
System.out.println(boy.getName());
boy.setNameNoCovered("小李");
System.out.println(boy.getName());
}
}
测试类执行结果:
null
null
小李
构造方法
构造方法也叫构造器或构造函数,作用是在创建对象时给成员变量进行初始化(即赋值)。
构造方法的格式:
public class Student {
// 构造方法
修饰符 类名(参数) {
方法体;
}
}
注意:
方法名必须和类名完全相同。
没有返回值类型,连 void 也不能有。
没有返回值,不能有 return 语句,即便是return;也不能有。
使用空参构造方法时成员变量被初始化为默认值。空参构造方法的方法体都是空的,什么都不写。
可以自定义带参构造方法,在方法体内可以给成员变量赋值。带参构造的形参不一定是全部成员变量,可能只有部分成员变量,在构造方法体内只给部分成员变量赋值。
构造方法在创建对象时由虚拟机自动调用,不能手动调用构造方法。每创建一次对象,虚拟机就会自动调用一次构造方法。
如果没有自定义的构造方法,那么虚拟机会自动添加一个空参构造方法,所以此时空参构造方法也不需要我们自己手动书写。
如果自定义了有参构造,那么虚拟机将不再提供默认的无参构造,在创建对象时将不能再使用无参构造。如果还需要使用无参构造,则需要我们自己手动书写无参构造。因此,建议如果写了自定义的有参构造,那么不管是否会用到无参构造,都再手动书写一个无参构造。
综上,要么自己一个构造函数也不要写,要么空参和带参的构造函数都自己手动书写。
带参构造和无参构造是构造方法的重载。
程序示例:
JavaBean 类:
public class Student {
private int age;
private String name;
// 空参构造,虚拟机自动添加的构造方法就和这个长得一样
public Student() {
}
// 带参构造
public Student(int age, String name) {
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
测试类:
public class StudentTest {
public static void main(String[] args) {
Student student1 = new Student();
System.out.println(student1.getAge()); // 0
System.out.println(student1.getName()); // null
Student g2 = new Student(23, "小张");
System.out.println(g2.getAge()); // 23
System.out.println(g2.getName()); // 小张
// 进行修改
g2.setAge(25);
g2.setName("小王");
System.out.println(g2.getAge()); // 25
System.out.println(g2.getName()); // 小王
}
}
浙公网安备 33010602011771号