第三章 面向对象
面向过程和面向对象设计思想
面向过程(POP)
- 解决问题时按照具体的实现步骤一步一步实现
面向对象(OOP)
- 对客观的事物进行分类(设计类)
- 实际使用时,先对整体关系做出划分,然后根据划分做具体的细化,需要以类为模板创建出一个个具体的对象
面向对象在宏观整体上对事物的关系进行设计,在进行具体实现时又回到了面向过程,两者相辅相成
类
什么是类?
- 一个模板,对同一类事物属性和方法的抽象
1.类的基本结构
- 成员变量 名词 属性
- 成员方法 动词 行为
- 构造方法 专职作用
- 内部类
- 代码块
/*所有类定义的时候可以添加属性和方法,但是不是必须要有的
* 一个java文件中可以定义n多个class,但只能有一个public class并且public class的类名跟文件名保持一致
*
* 属性:
* 语法:
* [访问修饰符] 数据类型 属性名称 = [值];
* 注意:
* 定义属性的时候可以有值也可以没有值,但必须包含属性的名称
*
* 方法:表示行为
* 语法:
* [访问修饰符] 返回值类型(任何类型) 方法名称(形参列表){
* 逻辑代码
* }
注意:
* 1.方法的访问修饰符可以不写
* 2.方法可以有返回值,也可以没有,void表示没有返回值的意思
* 3.形参列表可以有也可以没有
* 4.java中方法的传参都是值传递
*
* 对象的创建和使用
* 1.使用new关键字来创建对象
* ClassName objectName = new ClassName();
* 2.对象的使用:
* 使用对象的时候可以通过:
* 对象.属性
* 对象名称.方法
*/
package Car;
/*
发现类 汽车类
public(访问权限修饰)class(关键字修饰类)Car(类名)
*/
public class Car {
/*
定义类的成员变量 名词 属性
直接定义在类中,称为类的成员
可以使用java所支持的任意数据类型
成员变量在定义时可以不对其进行初始化,java会在默认方法中自动对其初始化
创建对象时,会从类中向对象中复制一份成员变量到对象中
*/
String name;
String color;
float price;
/*
定义类的成员方法 动词 行为
*/
public void run(){
System.out.println("car is running......");
}
public void stop(){
System.out.println("car is stop......");
}
}
package Car;
/*
类是模板,是抽象概念,是一个定义
对象是具体,可以直接使用的,是以类为模板,在内存中创建出来的实际存在的实例
Car bm = new Car();
Car():构造方法的名字与类名相同
new Car():new关键字,创建对象 以car为模板,在内存中创建一个具体实例
将类模板中的成员向具体对象中复制一份,每个对象都是独一无二的
Car bm:声明了一个类型为Car的变量bm
*/
public class TestCar {
public static void main(String[] args) {
Car bm = new Car();
bm.name = "宝马";
bm.color = "green";
bm.price = 20000;
System.out.println(bm.name+bm.color+bm.price);
bm.run();
bm.stop();
}
}
2.构造方法
package CarUp;
public class Car {
String name;
//public String name; 为后面引用传递传参声明为public
String color;
float price;
//创建完类后,如果没有手动调用构造方法,会有一个默认的无参的构造方法供调用
//当用户自定义了构造方法之后,默认的无参构造方法就不能够使用了
//同一个类中可以包含多个同名的构造方法
//引用类型null 整数0 浮点数0.0 char ‘ ’ boolean false
public Car(){
//无参构造方法
//一般情况下,如果定义了有参的构造方法,最好把无参的构造方法定义出来
}
public Car(String name,String color,float price){
//有参构造方法
this.name = name;
this.color = color;
this.price = price;
}
// 重载:
// 一个类中可以包含多个重名的方法,但是注意方法的参数列表不能相同
// 三个方面:
// 1.参数的个数
// 2.参数的类型
// 3.参数的顺序
// 注意:
// 一般构造方法都会进行重载(一个类中可能包含多个属性值,当只需要给部分属性初始化的时候需要调用不同的构造方法)
public Car(float price,String color,String name){
this.price = price;
this.color = color;
this.name = name;
}
public void run(){
System.out.println(this.name+" is running......");
}
//成员方法的重载
public void run(int speed){
System.out.println(this.name+"汽车以"+speed+"行驶");
}
public void stop(){
System.out.println(this.name+" car is stop......");
}
}
package CarUp;
public class TestCar {
public static void main(String[] args) {
/*
new Car(); 构造方法
作用:在构造方法中为创建的对象初始化赋值
语法:
方法名称:构造方法的名称必须跟类的名称保持一致
访问修饰符:
形参:可以用户自定义添加,跟方法的普通参数一样
方法体:完成对象的初始化功能
返回值:没有返回值
*/
Car bm = new Car();
bm.name = "宝马";
bm.color = "green";
bm.price = 20000;
bm.run();
bm.run(200);
Car bc = new Car("奔驰","red",3000000);
bc.run();
}
}
3.引用类型
栈
存放局部变量
先进后出,自上而下存储
方法执行完毕,自动释放空间
堆
存放new出来的对象
需要垃圾回收器来回收
方法区
存放类的信息(代码)、static变量、字符串常量等
4.this关键字
/*
*this:表示当前对象的指针
* 指向当前对象,表示当前对象的引用
* 用处:
* 1.构造方法:当构造方法中的参数名称跟类的成员变量名称一样时可以使用this.名称代表当前参数
* 注意:
* 1.有了this之后,可以将构造方法的参数跟成员变量保持一致
* 2.当构造方法中需要调用其他构造方法时,可以使用this()[必须要位于第一行],相当于this.ThisDemo()[此写法禁止使用]
* 2.普通方法中:当多个方法之间需要调用的时候,可以使用this来进行调用,指的是当前对象的其他方法
* 3.普通成员变量的使用:当方法中的参数名称跟成员变量保持一致的时候,使用this.表示的是对象的值,而使用变量名称表示的是形参列表中的值
*/
5.引用传递与值传递
引用传递
package CarUp.Demo1;
import CarUp.Car;
public class TestValue {
public static void main(String[] args) {
TestValue t = new TestValue();
Car car1 = new Car();
car1.name = "bc";
t.test(car1);
System.out.println(car1.name);//dz
}
//引用传递:传递的不是对象的本身,而是引用对象的地址
public void test(Car car2){
System.out.println(car2.name);//bc
car2.name = "dz";
}
}
值传递
package CarUp.Demo1;
public class TestValue {
public static void main(String[] args) {
int a = 10;
TestValue t = new TestValue();
t.test(a);
System.out.println(a);//10
}
//值传递:方法执行中形式参数的改变不影响实际参数的值
public void test(int b){
System.out.println(b);//10
b = 20;
}
}
6.static关键字
package CarUp.Demo2;
/*
* static:
* 1.修饰成员变量的时候,表示静态成员变形量或者叫类变量
* 普通变量在使用时,必要要通过对象名进行调用
* 类变量或者静态变量可以使用对象名也可以使用类名进行调用
* 注意:
* 1.静态变量在创建对象之前被初始化,或者说在类被载入之前进行初始化
* 2.静态变量被所有的对象共享,属于公共变量,对象和类都可以直接调用,但是推荐使用类来调用
* 3.成员变量放在堆中,而静态变量放在方法区中的静态区
* 4.静态变量不允许定义在静态方法中
* 5.静态方法可以在非静态方法中被调用
* 6.非静态方法不能在静态方法中被调用,如果需要,通过new的方式来调用
* public static void test(){
* new StaticDemo().test2();
* }
* 7.静态方法中不允许出现this,super等方法
* 8.一般工具类中的方法定义为static
*
* 2.修饰方法的时候,表示静态方法或者类方法
* 普通方法在使用的时候必须通过对象名调用,类方法或者静态方法可以使用类名,也可以使用对象名
* */
public class Aodi {
/*
Aodi 他们的名字都叫奥迪,在定义类的时候直接对其进行赋值
型号和价格是不一样的
*/
String model;
float price;
//static修饰的成员变量在内存中只有一份,所有成员共享,随着类的加载而加载
static String name = "Aodi";
}
package CarUp.Demo2;
public class TestAodi {
public static void main(String[] args) {
Aodi a8 = new Aodi();
a8.model = "a8";
a8.price = 3000000;
//一般建议静态变量通过类名来调用
System.out.println(Aodi.name+":"+a8.model+":"+a8.price);
}
}
7.代码块
/* 代码块:使用{}括起来的一段代码
* 分类:
* 普通代码块:定义在方法中的用{}括起来的代码
* 构造代码块:定义在类中的使用{}括起来的代码
* 注意:1.每次代码运行的时候,会将构造代码块中的代码添加到构造方法的前面
* 2.构造代码块中的代码会添加到每一个构造方法中,当使用this()的时候不会添加
* 静态代码块:使用static{}括起来的代码,在程序载入的时候优先执行
* 数据库连接等其他需要提前准备好的代码会放在static代码块
* 同步代码块:在多线程的时候使用,用来给共享空间加锁操作
*
* 执行顺序:静态-》构造-》普通
* */
public class CodeBlockDemo {
int a;
int b;
static{
System.out.println("静态代码块");
}
public CodeBlockDemo(){
System.out.println("构造方法");
}
public CodeBlockDemo(int a){
//会添加System.out.println("构造方法");
this.a = a;
}
public CodeBlockDemo(int a,int b){
this(a);//不会添加System.out.println("构造方法");,因为this(a)里面已经包含了
this.b = b;
}
{
System.out.println("构造代码块");//构造代码块
}
public void test(){
System.out.println("test");
{
System.out.println("what is this?");//普通代码块
}
}
public static void main(String[] args) {
CodeBlockDemo codeBlockDemo = new CodeBlockDemo(1,2);
codeBlockDemo.test();
{
System.out.println("main");
}
}
}
“构造代码块”);//构造代码块
}
public void test(){
System.out.println("test");
{
System.out.println("what is this?");//普通代码块
}
}
public static void main(String[] args) {
CodeBlockDemo codeBlockDemo = new CodeBlockDemo(1,2);
codeBlockDemo.test();
{
System.out.println("main");
}
}
}