面向对象编程和面向过程编程
面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。
面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。
例如五子棋,面向过程的设计思路就是首先分析问题的步骤:1、开始游戏,2、黑子先走,3、绘制画面,4、判断输赢,5、轮到白子,6、绘制画面,7、判断输赢,8、返回步骤2,9、输出最后结果。把上面每个步骤用分别的函数来实现,问题就解决了。
而面向对象的设计则是从另外的思路来解决问题。整个五子棋可以分为 1、黑白双方,这两方的行为是一模一样的,2、棋盘系统,负责绘制画面,3、规则系统,负责判定诸如犯规、输赢等。第一类对象(玩家对象)负责接受用户输入,并告知第二类对象(棋盘对象)棋子布局的变化,棋盘对象接收到了棋子的i变化就要负责在屏幕上面显示出这种变化,同时利用第三类对象(规则系统)来对棋局进行判定。
可以明显地看出,面向对象是以功能来划分问题,而不是步骤。同样是绘制棋局,这样的行为在面向过程的设计中分散在了总多步骤中,很可能出现不同的绘制版本,因为通常设计人员会考虑到实际情况进行各种各样的简化。而面向对象的设计中,绘图只可能在棋盘对象中出现,从而保证了绘图的统一。
功能上的统一保证了面向对象设计的可扩展性。比如我要加入悔棋的功能,如果要改动面向过程的设计,那么从输入到判断到显示这一连串的步骤都要改动,甚至步骤之间的循序都要进行大规模调整。如果是面向对象的话,只用改动棋盘对象就行了,棋盘系统保存了黑白双方的棋谱,简单回溯就可以了,而显示和规则判断则不用顾及,同时整个对对象功能的调用顺序都没有变化,改动只是局部的。
C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。
JAVA是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成。
类和对象的关系
类就是一类对象的统称。对象就是这一类具体化的一个实例。
简单的例子:我们平常在搭建房子之前都要先画好图纸,然后才能根据图纸盖房子,此时的图纸就相当于一个类,由类产生了房子这个对象
总的来说:类相当于一个模板,对象是由模板产生的样本。一个类,可以产生无数的对象。
类的基础语法和实例化
类的基础语法
声明一个类就是创建一个新的数据类型,而类在 Java 中属于引用类型, Java 使用关键字 class 来声明类(类似于C语言中的结构体,都属于自定义类型)。我们来
看以下简单的声明一个类。
// 创建类
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();//通过new实例化对象
person.eat();//成员方法调用需要通过对象的引用调用
person.sleep();
//产生对象 实例化对象
Person person2 = new Person();
Person person3 = new Person();
}
}
只有在实例化一个对象之后,才产生了具体的一个人,这个人具有年龄性别姓名等属性
注意:
局部变量p会在栈上开辟一块内存,后面的Person会在堆上开辟一块空间
访问对象的方法
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
注意事项
使用 . 访问对象的字段.
“访问” 既包含读, 也包含写(即可以给其赋值,比如给name赋值)
对于一个对象的字段如果没有显式设置初始值, 那么会被设置一个默认的初值.
默认值规则
对于各种数字类型, 默认值为 0.
对于 boolean 类型, 默认值为 false.
对于引用类型(String, Array, 以及自定制类), 默认值为 null
匿名对象
匿名只是表示没有名字的对象.
1.没有引用的对象称为匿名对象.
2.匿名对象只能在创建对象时使用.
3.如果一个对象只是用一次, 后面不需要用了, 可以考虑使用匿名对象.
static关键字
static关键字修饰的成员变量和成员方法都是不依赖于对象的,直接可以通过类名访问的
例:
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
代码块
使用 {} 定义的一段代码即为代码块,代码块又分为静态代码块,实例代码块,普通代码块等。
普通代码块
例:
public class Main{
public static void main(String[] args) {
{ //直接使用{}定义,普通方法块
int x = 10 ;
System.out.println("x1 = " +x);
}
int x = 100 ;
System.out.println("x2 = " +x);
}
}
// 执行结果
x1 = 10
x2 = 100
实例代码块
class Person{
private String name;//实例成员变量
private int age;
private String sex;
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()!");
}
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();
}
}
// 运行结果
I am instance init()!
I am Person init()!
name: bit age: 12 sex: man
实例代码块定义在类中的代码块(不加修饰符),一般用于初始化实例成员变量。
静态代码块
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();//静态代码块是否还会被执行?
}
}
注意事项
1.先执行静态代码块,再执行实例代码块,再执行构造方法
2.静态代码块只能执行一次
3.静态代码块中不能使用非静态数据
4.静态代码块在类加载的过程中执行
4.若都是静态或都是实例的,和定义的先后顺序有关