Java之面向对象
一、面向对象和面向过程
两者的区别是 :面向过程注重的是过程,就是在整个过程中所涉及的每一个行为(功能)。即用代码来描述每一步所需要做的事情,然后通过逻辑使代码串通起来。
面向对象注重的是对象,也就是参与过程所涉及到的每个主体,然后通过逻辑将一个个对象的功能实现连接起来,面向对象就是用代码(类)来描述客观世界的事物的一种方式。
在进行面向对象设计时,我们需要知道如何从类找对象,通过new来创建对象,使用对象,并维护对象之间的关系
二、类和类的实例化
类就是一类对象的统称,对象就是这一类具体化的一个实例。
简单来说类就相当于一个模板,由这个模板可以产生多个实例,比如人这个类有姓名、年龄、身份证等,但是每个人的信息却不相同,每个人都是人这个类的实例。
声明类的基本语法
创建类:
class <class_name>{
field;//成员属性
method;//成员方法
}
由类产生对象(实例化):
<class_name> <对象名> = new <class_name>();
示例如下:
class Person{
//包含:
//成员变量
public String name;
public int age;
//成员方法
public void eat(){
System.out.println(name + "吃饭!");
}
}
public class Main{
public static void main(String[] args) {
//通过new来实例化对象,然后通过引用来访问对象(用“ . ”来访问对象)
Person person = new Person();
//为成员变量赋值
person.name = "zhangsan";
//调用成员方法
person.eat();
//可以实例化多个对象
Person person1 = new Person();
Person person2 = new Person();
}
}
声明一个类就是创建一个新的数据类型,而类在 Java 中属于引用类型, Java 使用关键字 class 来声明类。
三、类的成员
1、成员变量
(1)定义
成员变量也可以叫为“ 字段 ”、“ 属性 ”
成员方法主要用于描述一个类中包含哪些数据
(2)初始值
对于一个对象的成员变量,如果没有主动设置初始值的话, 那么会被设置成一个默认值
(3)关于null
null 在 Java 中为 “空引用”, 表示不引用任何对象,如果对null进行引用,就会发生空指针异常。
2、成员方法
成员方法是用来描述对象的“ 行为 ”的
构造方法
这里重点介绍下构造方法
构造方法是用来构造对象的
① 注意:
(1)构造方法是在实例化对象的时候会被自动调用到的方法,,方法名字和类名相同,用于对象的初始化。构造方法之间构成了重载
(2)虽然我们前面已经能将属性初始化了, 但是有些时候可能需要进行一些更复杂的初始化逻辑, 那么就可以使用构造方法来初始化对象
(3)当我们使用关键字“ new ”来实例化对象的时候,构造方法就会被自动调用了
② 语法规则:
(1)方法名称与类的名称相同
(2)构造方法没有返回值类型
(3)每个类中都会有构造方法,如果自己没有声明构造方法的话,编译器会默认生成一个不带参数的构造方法,如果当前类有其他的构造方法了,那么编译器就不会生成不带参数的构造方法了,除非自己定义。
代码示例:
class Person {
private String name;
private int age;
public Person() {
System.out.println("不带参数的构造方法!");
}
public Person(String name) {
//this代表当前对象的引用,后面会介绍
this.name = name;
System.out.println("带一个String类型参数的构造方法!");
}
public Person(String name,int age) {
this.name = name;
this.age = age;
System.out.println("带2个(String,int)类型参数的构造方法");
}
public class Main {
public static void main2(String[] args) {
//选择合适的构造方法
Person person1 = new Person();
Person person2 = new Person("zhangsan");
Person person3 = new Person("zhangsan",20);
}
}
3、static关键字
class Person{
//普通成员变量
public String name;
public int age;
//静态成员变量(类变量)
public static int count;
//静态成员方法(类方法)
public static void staticFunc(){
System.out.println("static::func()");
}
}
public class Main{
public static void main(String[] args) {
Person person1 = new Person();
person1.age++;//1
person1.count++;//1
System.out.println(person1.count);
System.out.println("================");
Person person2 = new Person();
person2.age++;//1
person2.count++;//2
System.out.println(person2.count);
Person.staticFunc();
}
}
由上述代码可知由“ static ”修饰的静态成员变量/方法是属于类的,不依赖对象,即不需要“ new ”对象就可以使用,所以可以通过类名来访问静态变量/方法
注意:
(1)普通的方法内部,不能够定义静态的变量
(2)静态方法内部不可以调用普通的方法
4、代码块
(1)示例
class Person{
private String name;
private int age = 18;
public static int count;
{
this.age = 99;
System.out.println("实例代码块!");
}
static {
count = 99;
System.out.println("静态代码块!");
}
}
(2)代码块的调用
代码块调用的顺序:静态代码块执行 -> 实例代码块 执行-> 构造函数执行。
注意:在同一个类中创建进行多个对象实例化后,静态代码块不用实例化对象都能执行,且只执行一次。
四、封装
1、private实现封装
被 public 修饰的成员变量或者成员方法, 可以直接被其他类使用
被 private 修饰的成员变量或者成员方法, 不能被其他类使用
为什么要使用“ private ”来实现封装呢?
以类Person为例
直接使用“ public ”时,类的调用者必须要了解 Person 类内部的实现,才能够使用这个类,导致学习成本较高;并且一旦类的实现者修改了代码(例如把 name 改成 myName),那么类的使用者就需要大规模的修改自己的代码, 导致维护成本较高。
所以我们可以使用 “ private ”封装属性, 并提供“ public ”方法供类的调用者使用。
通常情况下我们会把字段设为“ private ”属性,但是方法是否需要设为“ public ”, 就需要视具体情形而定。一般我们希望一个类只提供 “必要的” public 方法,,而不应该是把所有的方法都无脑设为 public。
2、使用getter和setter方法
当我们使用 “ private "来修饰字段的时候, 就无法直接使用这个字段了,此时如果需要获取或者修改这个“ private ”属性,就需要使用 getter /setter 方法。
class Person {
private String name;
private int age;
//setName即为setter方法,表示设置这个成员的值
public void setName(String name){
this.name = name;//this引用:表示当前对象的引用
}
//getName即为getter方法,表示获取这个成员的值
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("lisi");
String name = person.getName();
System.out.println(name);//lisi
person.show();//name: lisi age: 0
}
五、toString方法
可以使用 toString 方法来将对象自动转成字符串
class Person {
private String name;
private int age;
public void show() {
System.out.println("name:"+name+" " + "age:"+age);
}
//重写toString方法
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class Main {
public static void main(String[] args) {
Person person = new Person();
person.name = "zhangsan";
perosn.age = 18;
System.out.println(person);//执行结果为:Person{name='zhangsan', age=18}
}
}