引入
程序员中有句话叫万物皆对象
一、面向对象是什么
面向对象是一种编程方式,即按照人类正常的思维方式去思考问题、编写代码,所谓人类正常的思维方式,就是对事物的总结归纳,比如做如下的事:想在计算机世界模拟现实世界中一条年龄是5岁的、身高1米的、叫大黄的狗,这条狗能跑、能咬东西,就需要按照下图的流程去进行
具体流程如下
1、由现实世界到程序员脑海世界
总结叫大黄的这只狗所在群体的共同特征,特征包括静态特征(属性)、动态特征
(行为),属性用变量表示,行为用方法表示,具体代码见图
2、由程序员脑海世界到计算机世界
流程1中创建了狗类并没有实际意义,需要具体化到某一个实体,因此使用如下代码格式去创建对象
类名 变量名 = new 类名();
运行到此时的具体内存图为
(1)程序运行时,需要先将Dog类型加载到方法区
(2)执行Dog i = new Dog();语句,Dog i;这句话相当于在栈内存中声明一个Dog类型的变量i,然后执行new Dog();语句,这句话中有new关键字,之前介绍过new关键字干的事是在堆内存中,因此执行这句话会创建一个Dog类的对象,由于Dog类中有属性(name、age、height),系统会为这些属性创建默认值,比如String型的name,默认值就是null,创建好对象,该对象会有句柄指向其属于的Dog类型,同时会将该对象在堆中的地址传递给栈中的i变量
(3)由于在创建对象后,给该对象的各个属性值更改,因此内存图需要变更为
三 不同编程方式对比
比较主流的编程方式主要有面向过程和面向对象
如场景取钱
如果采用面向过程方式去编程,程序员更关注取钱的整个流程,第一步插卡、第二步输密码、第三步输入取的金额、第四步取出钱、第五步取出卡
如果采用面向对象编程方式去编程,程序员更关注取钱涉及到的实体,包括取钱的人、取的钱、取钱用的卡、取钱之后的收据
四 相关概念
1、类 同一种事物公共的属性和行为的抽取,比如人类、狗类
(1)具体声明格式
[类修饰符] class 类名{ 类的成员 … }
比如创建Person类
public class Person{
public String name;
public char sex;
public void say(){
}
}
(2)类中可写的东西
属性
方法
代码块
内部类
2、对象 真实存在的实体,比如邻居家的那条狗,门口停的一台车
(1)具体创建格式
new 类名();
比如创建Person类的对象
new Person();
(2)类是创建对象的模板,对象是类的具体化实例
3、成员变量、局部变量
(1)成员变量是写在类中的变量,与方法平级,就是属性
public class Test4 {
public int i;
public void b(){
}
}
上边代码中的i就是成员变量
(2)局部变量是写在方法中的变量,我们之前遇到的变量都是写在方法中,因此之前接触的变量都是局部变量
(3)成员变量和局部变量区别在于成员变量位于堆内存,局部变量位于栈内存,成员变量随着对象的创建即拥有默认值,局部变量需要第一次赋值才能使用
public class Test4 {
public int i;
public void b(){
int i;
}
public static void main(String[] args) {
Test4 h = new Test4();
h.b();
}
}
如上代码,内存图为
上述代码和内存图可以看到,堆中对象的i变量和栈中b()方法中的i变量分别位于不同的内存区域,因此不同
(4)成员变量和局部变量同名
由于存在就近原则,第7行打印出的i是b方法的局部变量,为了打印出成员变量的i需要像第8行打印this.i,this表示当前对象
本章所有的成员变量前都加public,方法前加public不加static
五、对象的使用
使用其他类的属性,格式是对象名.属性
使用其他类的方法,格式是对象名.方法
例
public class Test4 {
public static void main(String[] args) {
A p = new A();
System.out.println(p.i);
p.hhh();
}
}
class A{
public int i;
public void hhh(){
}
}
六、构造器
以上讲过,创建对象使用new 类名();的语句,这里类名()叫构造器,也叫构造方法
1、构造器(构造方法/构造器,Constructor)特点:
构造方法名必须与类相同的名称
不含返回值类型,也没有void
不能在方法中用return语句返回一个值
比如创建A类对象用到的A(),就是A类的构造器
2、构造器的声明
[访问修饰符] 类名(参数列表){
}
例如为A类创建一个无参构造器
public A(){
}
说明
(1)在Java中,每个类都至少要有一个构造器
(2)一个类可以不写出构造方法,编译器会自动的给这个类增加一个构造器,该构造器没有任何参数,我们称之为“默认的空构造器”。
比如A类即使不声明构造器,这个类也会默认带一个无参构造器,如果A类中明确声明一个有参构造器,就不会默认自带无参构造器了,因此在外界调用构造器时会发生错误
3、构造器重载
前几章讲过方法的重载,由于构造器也是方法的一种,因此构造器也会发生重载现象
七、package和import
1、前期课程介绍过,我们在创建JAVA项目后,需要将JAVA文件装入一个个的包中,便于我们管理,包的声明关键字是package,必须位于JAVA文件的第一行,JAVA中常用的包有java.lang,java.util
2、如果类中使用了其他包中的类,需要使用import关键字
具体格式为
import 包名.类名
比如引入Scanner
package com.test;
import java.util.Scanner;
public class Test4 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
}
}
class A{
public A(int i){
}
}
八、static关键字
static表示静态的,可以修饰成员变量、方法、代码块
1、static属性
(1)用static修饰的属性,它们在类被载入时创建
class A{
public static int h;
}
(2)两种方式访问:
直接访问:类名.属性;
实例化后访问:对象名.属性
静态变量被所有的对象所共享,非静态变量是对象所拥有
例
public class Test4 {
public static void main(String[] args) {
A a = new A();
System.out.println(a.h);
System.out.println(a.i);
A a1 = new A();
a1.h = 1;
a1.i = 1;
System.out.println(a.h);
System.out.println(a.i);
}
}
class A{
public static int h;
public int i;
}
运行结果
(1)可以看到,h变量是static变量,因此A类所用对象共享h变量,即A类的一个对象改变了h的值,其他对象就会获取到这个值
(2)而i变量是非static变量,因此各对象的i变量相互独立,其中一个对象改变了i的值,不会影响其他对象中i的值
(3)h变量可以通过A.h取得
2、静态方法
静态方法不需要实例化,可以直接访问,访问方式:
直接访问:类名.方法名()
实例化后访问:对象名.方法名()
例
public class Employee{
public static void add(){
}
}
public class Test{
public static void main(String[] args) {
Employee.add();//直接调用静态方法
Employee emp = new Employee();
emp.add();//可以,但不建议使用
}
注意事项
3、静态语句块
一个类中由static关键字修饰的,不包含在任何方法体中的代码块
当类被载入时,静态代码块被执行,且只被执行一次
静态块经常用来进行类属性的初始化
例
4、静态方法只能直接访问静态属性和静态方法
5、非静态方法可以直接访问非静态属性、非静态方法和静态属性、静态方法