1.类和对象
1.1认识面向对象
C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。 JAVA是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成。
面向过程注重的是过程,在整个过程中所涉及的行为,就是功能。
面向对象注重的是对象,也就是参与过程所涉及到的主体。是通过逻辑将一个个功能实现连接起来
【面向对象设计】 面向对象设计把握一个重要的经验:谁拥有数据,谁对外提供操作这些数据(私有)的方法!(被动的一方是数据的拥有者,主动的一方是执行者) 开发时:找对象,建对象,用对象,并维护对象之间的关系
1.2类和类的实例化
基本语法:
class <class_name>{
field;
method;
}
<class_name> <对象名> = new <class_name>();
class为定义类的关键字,ClassName为类的名字,{}中为类的主体。 类中的元素称为:成员属性。类中的函数称为:成员方法
类的实例化
如下代码:
class Person {
public int age;
public String name;
public String sex;
public void eat() {
System.out.println("吃饭!");
}
public void sleep() {
System.out.println("睡觉!");
}
}
public class Main{
public static void main(String[] args) {
Person person = new Person();
person.eat();
person.sleep();
Person person2 = new Person();
Person person3 = new Person();
}
}
注意:
- new 关键字用于创建一个对象的实例
- 使用 . 来访问对象中的属性和方法
- 同一个类可以创建多个实例
1.3类的成员
类的成员可以包含以下:字段,方法,代码块,内部类和接口等。此处我们只介绍前三个
1.3.1字段/属性/成员变量
在类中, 但是方法外部定义的变量. 这样的变量我们称为 “字段” 或 “属性” 或 “成员变量”(三种称呼都可以, 一般不会严格区分).
用于描述一个类中包含哪些数据
class Person{
public String name;
public int age;
}
class Test{
public static void main(String[] args){
Person person = new Person();
System.out.println(person.name);
System.out.println(person.age);
}
}
null
0
注意:
- 使用 . 访问对象的属性
- "访问"既包含读,也包含写
- 对于一个对象的属性如果没有显式赋值,就会被设置一个默认的初始值
1.3.2方法
关于方法的使用请参考作者的本篇博客
方法的使用详解
1.3.3 static 关键字
- 修饰属性
- 修饰方法
- 代码块
- 修饰类(暂时不涉及)
1.3.3.1修饰属性
Java静态属性和类相关, 和具体的实例无关. 换句话说, 同一个类的不同实例共用同一个静态属性。静态成员变量通过类名进行访问
如下代码:
class TestDemo{
public int a;
public static int count;
}
public class Main{
public static void main(String[] args) {
TestDemo t1 = new TestDemo();
t1.a++;
TestDemo.count++;
System.out.println(t1.a);
System.out.println(TestDemo.count);
System.out.println("============");
TestDemo t2 = new TestDemo();
t2.a++;
TestDemo.count++;
System.out.println(t2.a);
System.out.println(TestDemo.count);
}
}
输出结果:
1 1
============
1 2
1.3.3.2修饰方法
如果在任何方法上应用 static 关键字,此方法称为静态方法
- 静态方法属于类,而不属于类的对象。
- 可以直接调用静态方法,而无需创建类的实例。
- 静态方法可以访问静态数据成员,并可以更改静态数据成员的值
如下代码:
class TestDemo{
public int a;
public static int count;
public static void change() {
count = 100;
}
}
public class Main{
public static void main(String[] args) {
TestDemo.change();
System.out.println(TestDemo.count);
}
}
100
注意事项1: 静态方法和实例无关, 而是和类相关. 因此这导致了两个情况:
静态方法不能直接使用非静态数据成员或调用非静态方法(非静态数据成员和方法都是和实例相关的). this和super两个关键字不能在静态上下文中使用(this 是当前实例的引用, super是当前实例父类实例的引用, 也是和当前实例相关). 注意事项2: 我们曾经写的方法为了简单, 都统一加上了 static. 但实际上一个方法具体要不要带 static, 都需要是情形而定. main 方法为 static 方法
2.封装
在我们写代码的时候经常会涉及两种角色: 类的实现者和类的调用者.
封装的本质就是让类的调用者不必太多的了解类的实现者是如何实现类的, 只要知道如何使用类就行了.
这样就降低了类使用者的学习和使用成本, 从而降低了复杂程度
2.1 四种访问权限修饰符
Java权限修饰符public、protected、(缺省)、private置于类的成员定义前,用来限定对象对该类成员的访问权限。
一般情况下我们只使用 private 来实现封装
注意事项:
- private 不光能修饰字段, 也能修饰方法
- 通常情况下我们会把字段设为 private 属性, 但是方法是否需要设为 public, 就需要视具体情形而定. 一般我们希望一个类只提供 “必要的” public 方法, 而不应该是把所有的方法都无脑设为public
2.2 getter 和 setter 方法
当我们使用 private 来修饰字段的时候, 就无法直接使用这个字段了。如果需要获取或者修改这个 private 属性, 就需要使用 getter / setter 方法
class Person {
private String name;
private int age;
public void setName(String name){
this.name = name;
}
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("superman");
String name = person.getName();
System.out.println(name);
person.show();
}
superman
name: superman age: 0
注意事项
- getName 即为 getter 方法, 表示获取这个成员的值.
- setName 即为 setter 方法, 表示设置这个成员的值.
- 当set方法的形参名字和类中的成员属性的名字一样的时候,如果不使用this, 相当于自赋值. this 表示当前实例的引用.
- 不是所有的字段都一定要提供 setter / getter 方法, 而是要根据实际情况决定提供哪种方法.
- 在 IDEA 中可以使用 alt + insert (或者 alt + F12) 快速生成 setter / getter 方法. 在 VSCode 中可以使用鼠标右键
菜单 -> 源代码操作 中自动生成 setter / getter 方法.
3.构造方法
3.1构造器的使用
构造方法是一种特殊方法, 使用关键字new实例化新对象时会被自动调用, 用于完成初始化操作.
基本语法:
修饰符 类名 (参数列表) {
初始化语句;
}
根据参数不同,构造器可以分为如下两类:
- 隐式无参构造器(系统默认提供)
- 显式定义一个或多个构造器(无参、有参)
示例代码:
class Person {
private String name;
private int age;
private String sex;
public Person() {
this.name = "superman1";
this.age = 19;
this.sex = "男";
}
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 p1 = new Person();
p1.show();
Person p2 = new Person("superman2",99,"男");
p2.show();
}
}
name: superman1 age: 19 sex: 男
name: superman2 age: 99 sex: 男
注 意:
- Java语言中,每个类都至少有一个构造器
- 默认构造器的修饰符与所属类的修饰符一致
- 一旦显式定义了构造器,则系统不再提供默认构造器
- 一个类可以创建多个重载的构造器
- 父类的构造器不可被子类继承
3.2 this 关键字
this表示当前对象的引用(注意不是当前对象),可以借助this来访问对象的字段和方法 注意:静态方法中不可有 this 如下代码:
class Person {
private String name;
private int age;
private String sex;
public Person() {
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();
}
}
name: bit age: 12 sex: man
4.认识代码块
使用 {} 定义的一段代码.
根据代码块定义的位置以及关键字,又可分为以下四种:
- 普通代码块
- 构造块
- 静态块
- 同步代码块(多线程以后再说)
代码块的执行顺序:
静态 -> 构造-> 普通
普通代码块:定义在方法中的代码块(对此不再举例)
4.1构造代码块和静态代码块
构造块:定义在类中的代码块(不加修饰符)。也叫:实例代码块 静态代码块:使用static定义的代码块。一般用于初始化静态成员属性
class Person{
private String name;
private int age;
private String sex;
private static int count = 0;
public Person(){
System.out.println("I am Person init()!");
}
{
this.name = "bit";
this.age = 12;
this.sex = "man";
System.out.println("I am instance init()!");
}
static {
count = 10;
System.out.println("I am static init()!");
}
public void show(){
System.out.println("name: "+name+" age: "+
age+" sex: "+sex);
}
}
public class Main {
public static void main(String[] args) {
Person p1 = new Person();
Person p2 = new Person();
}
}
静态代码块不管生成多少个对象,其只会执行一次,且是最先执行的。
5.补充说明
5.1 toString 方法
可以使用 toString 方法来将对象自动转化为字符串 代码示例:
class Person {
private String name;
private int age;
public Person(String name,int age) {
this.age = age;
this.name = name;
}
public void show() {
System.out.println("name:"+name+" " + "age:"+age);
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class Main {
public static void main(String[] args) {
Person person = new Person("superman",19);
person.show();
System.out.println(person);
}
}
name:superman age:19
Person{name="superman", age=19}
注意:
- toString 方法会在 println 的时候被自动调用.
- 将对象转成字符串这样的操作我们称为 序列化.
- toString 是 Object 类提供的方法, 我们自己创建的 Person 类默认继承自 Object 类, 可以重写 toString 方法实现我们自己版本的转换字符串方法. (关于继承和重写这样的概念, 我们后面会重点介绍).
- @Override 在 Java 中称为 “注解”, 此处的 @Override 表示下面实现的 toString 方法是重写了父类的方法. 关于注解后面的课程会详细介绍.
- IDEA快速生成Object的toString方法快捷键:alt + f12(insert)
5.2匿名对象
匿名只是表示没有名字的对象.
- 没有引用的对象称为匿名对象.
- 匿名对象只能在创建对象时使用.
- 如果一个对象只是用一次,后面不需要用了,可以考虑使用匿名对象
代码示例:
class Person {
private String name;
private int age;
public Person(String name,int age) {
this.age = age;
this.name = name;
}
public void show() {
System.out.println("name:"+name+" " + "age:"+age);
}
}
public class Main {
public static void main(String[] args) {
new Person("superman",19).show();
}
}
name:superman age:19
重点总结
- 一个类可以产生无数的对象,类就是模板,对象就是具体的实例。
- 类中定义的属性,大概分为几类:类属性,对象属性。其中被static所修饰的数据属性称为类属性, static修饰的方法称为类方法,特点是不依赖于对象,我们只需要通过类名就可以调用其属性或者方法。
- 静态代码块优先实例代码块执行,实例代码块优先构造函数执行。
- this关键字代表的是当前对象的引用。并不是当前对象
|