##1. 什么是面向对象
概念:
Java是一门纯面向对象的语言(Object Oriented Program,继承OOP),在面向对象的世界里,一切皆为对象。面向对象是解决问题的一种思想,主要依靠对象与对象之间的交互来共同完成一件事情。
面向对象的优点
用面向对象的思想来涉及程序,更符合人们对事物的认知,对于大型程序的设计、扩展以及维护都非常友好。使用面向对象思想进行开发有以下优点:
1、易维护
采用面向对象思想设计的结构,可读性高,由于继承的存在,即使改变需求,那么维护也只是在局部模块,所以维护起来是非常方便和较低成本的。
2、质量高
在设计时,可重用现有的,在以前的项目的领域中已被测试过的类使系统满足业务需求并具有较高的质量。
3、效率高
在软件开发时,根据设计的需要对现实世界的事物进行抽象,产生类。使用这样的方法解决问题,接近于日常生活和自然的思考方式,势必提高软件开发的效率和质量。
4、易扩展
由于继承、封装、多态的特性,自然设计出高内聚、低耦合的系统结构,使得系统更灵活、更容易扩展,而且成本较低。
小结:
并不是说面向对象编程的就是最好的,主要还是要看自己的实际需求,一定记得"存在即合理"这句话。
类是什么
类是用来对一个实体(对象)来进行描述的,主要描述该实体(对象)具有哪些属性(外观尺寸等),哪些功能(用来干啥),描述完成后计算机就可以识别了。类是十分抽象的,例如世界上有很多的不同的人,但每个人都有头发,手,大脑等属性,以及吃饭,睡觉等等动作,所以我们可以把这些人所共有的东西抽象为一个类,也就是人类的概念。
如何定义一个类
语法格式:
// 创建类
//类名注意采用大驼峰定义
class ClassName{
(访问权限修饰符)(数据类型) 成员变量名;
// 字段(属性) 或者 成员变量
(访问权限修饰符)(返回类型)(数据类型)method;
// 行为 或者 成员方法(注意构造方法无返回值)
}
class为定义类的关键字,ClassName为类的名字,类名注意采用大驼峰定义(每个单词首字母大写),{}中为类的主体。类中包含的内容称为类的成员。属性主要是用来描述类的,称之为类的成员属性或者类成员变量。方法主要说明类具有哪些功能,称为类的成员方法。
例如定义一个洗衣机类
class WashMachine{
public String brand; // 品牌
public String type; // 型号
public double weight; // 重量
public double lenght; // 长
public double weidth; // 宽
public double height; // 高
public String color; // 颜色
public void WashClothes(){ // 洗衣服 System.out.println("洗衣功能"); }
public void dryClothes(){ // 脱水 System.out.println("脱水功能"); }
public void SetTime(){ // 定时 System.out.println("定时功能"); }
}
注意事项
2. main方法所在的类一般要使用public修饰(注意:Eclipse默认会在public修饰的类中找main方法)
3. public修饰的类必须要和文件名相同
4. 不要轻易去修改public修饰的类的名称,如果要修改,就一定要保证用public修饰的类名与文件名保持一致
概念
用**类类型创建对象的过程,称为类的实例化,在java中采用new关键字,配合类名(构造函数)来实例化对象。**定义了一个类,就相当于在计算机中定义了一种新的类型(一种引用类型),与int,double类似,只不过int和double是Java语言自带的内置类型,而类是用户自定义了一个新的类型也叫做(类)类型,这些自定义的类型之后,就可以使用这些类来定义实例(或者称为对象)。
实例化类以及对象访问成员变量和成员方法
1. new 关键字用于创建一个对象的实例.
2.使用 对象名. 来访问对象中的属性和方法.
3.同一个类可以创建多个实例.
例如
//定义一个学生类
class student{
public String name;
public int age;
public static String cla;
public void show(){
System.out.println("姓名:"+neme+"年龄:"+age+"cla:"+cla);
}
}
}
public class javademo1 {
public static void main(String[] args) {
//通过类student实例化一个学生对象
student stu=new student();
//通过对象访问初始化实例化成员变量
stu.name="二狗子";
stu.age=66;
stu.cla="黄傲婷";
}
}
实例化对象的过程,实质上是通过类在JVM的堆上开辟一份真实的物理内存空间,主要过程如下
1.检测创建对象所对应的类是否加载,如果没有加载则需要先加载。
2.在堆上为对象分配内存空间,并将其引用赋值给相对应的引用变量。
3.处理并发安全问题(多线程):也就是说防止多个线程分别创建对象时,在堆上的同一个地址空间上发生冲突
4.当对象的空间申请好之后,为已经创建好的对象数据成员进行初始化(就地初始化或默认初始化初始化)。
就地初始化:也就是在创建类的时候就将各成员进行赋值(写死了,不灵活),注意:代码编译完成后,编译器会将所有给成员初始化的这些语句添加到各个构造函数中。
package day1;
public class demo1 {
//通过就地初始化的方式进行对象成员初始化
public String name="张三";
public int age=55;
public static void main(String[] args) {
//实例化对象
demo1 t=new demo1();
System.out.println(t.name+" "+t.age);
}
}
默认初始化:当实例化对象时并没有对成员变量进行初始化时,对象的成员变量也会有默认值
5. 设置对象头信息(关于对象内存模型后面会介绍)
6. 调用构造方法,给对象中各个成员赋值
我们经常以为构造方法是用来给对象申请内存空间的,其实不然,构造方法往往是创建对象过程中的最后一步,用于对对象成员的赋初值,注意:这里的赋初值与前边对象开辟好空间后进行的成员初始化是不同的。
public class demo2 {
//通过就地初始化的方式进行对象成员初始化
public String name1;
public int age1;
public static void main(String[] args) {
//实例化对象
demo2 t=new demo2();
System.out.println(t.name1+" "+t.age1);
}
}
1. 类只是一个模型一样的东西,用来对一个实体进行描述,限定了类有哪些成员.
2. 类是一种自定义的类型,可以用来定义变量,但是在Java中用类定义出来的变量我们叫做(引用变量),也就是存放对象引用的变量.
3. 一个类可以实例化出多个对象,实例化出的对象 占用实际的物理空间,存储类成员变量
4. 做个比方。类实例化出对象就像现实中使用建筑设计图建造出房子,类就像是设计图,只设计出需要什么东西,但是并没有实体的建筑存在,同样类也只是一个设计,实例化出的对象才能实际存储数据,占用物理空间
Java编译器给每个“成员方法“增加了一个隐藏的引用类型参数,该引用参数指向当前对象(成员方法运行时调用该成员方法的对象),在成员方法中所有成员变量的操作,都是通过该引用去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成。
this引用的作用:
用同一个类在创建不同的对象之后,不同的对象在调用自己的成员变量以及成员方法时它是如何知道并调用的属于自己的成员变量以及方法的呢,其实在实例化一个类之后,this代表的是当前对象的引用,它能通过该引用实现非静态成员变量以及非静态成员方法的调用,所以到目前为止,我们知道【1】this是代表了一个对象的引用,【2】当类中的非静态成员方法中的局部变量参数与函数中访问类中的成员变量时发生重名的情况,此时this引用就可以帮我们区别函数参数与类的普通成员【3】一般情况下,this是可以不用写的,从本质来看,this是一个隐式的参数,由编译器自动调用。
例如
这里是引用
public class demo2 {
//通过就地初始化的方式进行对象成员初始化
public String name1;
public int age1;
public void setName1(String name1){
this.name1=name1;
}
public static void main(String[] args) {
//实例化对象
demo2 t=new demo2();
t.setName1("张三");
}
}
在调试过程中可以观察到,this引用的确代表的是当前对象的引用。
this的常见用法
1.this.类的实例成员
2.this.类的成员方法
3.this() 在类的构造函数中调用类的其他构造函数
,只能在构造函数中使用,且只能在构造方法第一行
使用注意
- 想要通过this调用类中的实例成员(成员属性)或者成员方法时,一定要先创建对象,因为this本质是代表一个对象的引用,只有通过对象才能访问对象中的实例成员或者成员方法
2.使用this()时,一定记得this()只能在一个类中的构造函数中使用且只能放在构造函数的第一行,还有就是使用this()时,调用的构造函数之间千万不要形成"环",也就是你调用我,我有调用我。
this引用的特性
1. this的类型:对应类类型引用,即哪个对象调用就是哪个对象的引用类型
2. this只能在"成员方法"中使用
3. 在"成员方法"中,this只能引用当前对象,不能再引用其他对象,具有final属性
4. this是“成员方法”第一个隐藏的参数,编译器会自动传递,在成员方法执行时,编译器会负责将调用成员方法对象的引用传递给该成员方法,this负责来接收
概念:
构造方法(也称为构造器)是一个特殊的成员方法,名字必须与类名相同,在创建对象时,由编译器自动调用,并且
在整个对象的生命周期内只调用一次。
注意:构造方法的作用就是对对象中的成员进行初始化,并不负责给对象开辟空间。
构造函数的特性:
1.名字与类名相同,没有返回值类型,设置为void也不行
2.一般情况下使用public修饰
3. 在创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次
4.构造方法的作用就是对对象中的成员进行初始化,并不负责给对象开辟空间
5.构造方法可以重载(用户根据自己的需求提供不同参数的构造方法
**6. 如果用户没有显式定义,编译器会生成一份默认的构造方法,生成的默认构造方法一定是无参的,一旦用户定义,编译器则不再生成
如图如果自定义了一个构造函数,那编译器就不会自动生成无参的构造函数,如果此时使用无参构造函数那编译器此时会报出错误
错误信息
类中的自定义构造函数例如
public class pack2demo1 {
String name;
int age;
String sex;
//构造函数1
pack2demo1 (){
System.out.println("这是packdemo2中的无参构造函数");
}
//构造函数2(与上方构造函数形成重载)
pack2demo1 (String name,int age,String sex){
this.age=age;
this.name=name;
this.sex=sex;
System.out.println("这是packdemo2中的带有3个参数的构造函数");
}
}
首先实例化对象的含义就是通过已经定义好的类创建一个对象,当我们在实例化对象的时候,一定会有以下两个步骤,但不一定只有这两个步骤,1.给对象分配内存 2.调用合适的构造方法给实例变量赋初始值,值得注意的是在实例化对象时,编译器会自动帮我们调用构造函数,如果我们没有写自己的构造函数,那系统会自动帮我们调用一个无参的构造函数,如果类中写入了构造函数,那实例化对象时,会优先调用自己的构造函数,且构造函数允许发生函数重载。
例如
package pack2;
public class pack2demo1 {
String name;
int age;
String sex;
//无参构造函数
pack2demo1 (){
System.out.println("这是packdemo2中的无参构造函数");
}
//带三个参数的构造函数(与上一个构造函数构成函数重载)
pack2demo1 (String name,int age,String sex){
this.age=age;
this.name=name;
this.sex=sex;
System.out.println("这是packdemo2中的带有3个参数的构造函数");
}
@Override
public String toString() {
return "pack1类中从写demo1{" +
"name='" + name + '\'' +
"age=" + age +
", sex='" + sex + '\'' +
'}';
}
public static void main(String[] args) {
//实例化对象demo1时调用无参的构造函数
pack2demo1 demo1 = new pack2demo1();
//实例化对象demo2时调用三个参数的构造函数
pack2demo1 demo2 = new pack2demo1("李四", 18, "男");
}
}
默认初始化:
我们知道在定义局部变量是一定需要进行初始化的,不然就会报错,而我们在类中定义实例成员变量时就算不进行初始化,也不会报错,且他们都有已经由构造器(构造函数)初始化好的值,本质上是在调用构造函数时。
就地初始化
就地初始化指的是在定义类的时候,就对类中的实例成员变量进行初始化;注意:代码编译完成后,编译器会将所有给成员初始化的这些语句添加到各个构造函数代码之前。
在实例化一个对象之后,我们有时可能会频繁的要对部分成员变量进行复制,或者获取成员变量,为了方便,那我们就必须要在类中定义相应的成员方法,那我们为了避免每定义一个类时都进行重复的操作,其实强大的开发工具已经为我们提供了快捷生成代码的方式快学习起来吧!
1.自动生成构造函数(可选参数)
2.自动获取成员变量和对其进行赋值方法的快捷方式,仅仅只需要将上方的第三步改为getter或者setter即可。
如果我们已经实例化好了一个对象,并将其对象引用进行打印,输出结果其实是一个哈希值(对象的地址)如下
那为什么在这里会有这样的输出呢,其实在打印对象引用可以细分出以下细节,可以发现其实之所以会打印出哈希值的代码主要代码是由toString方法的返回值决定的,所以我们只要通过重写Object类中的toString方法就可以实现输出打印对象的各成员变量和值
如下
public static void main(String[] args) {
dog dog1=new dog("小狗",66,"公的");
System.out.println(dog1);
}
}
class dog{
private String name;
private int age;
private String sex;
public dog(String name, int age, String sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
//String方法的重写
@Override
public String toString() {
return "dog{" +
"name='" + name + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
'}';
}