面向对象
方法:完成一个特定功能的代码块。
结构体:表达意义相近的变量组在一起,归为一类。
类:即有方法又包含结构体的对象。
面向对象的思维模式
这就是分类的思维模式,首先考虑解决问题需要哪些分类,然后对这些分类进行单独思考。最后,在对某个分类下面的细节进行面向过程的思索。
显然,面向对象适合处理复杂问题,更有利于多人分工协作。
对于描述复杂的事物,为了从宏观上把握、从整体上合理分析,我们需要使用面向对象的思路来分析整个系统。但是具体到具体操作,仍然需要面向过程的思路去处理。
什么是面向对象
java语言被称为面向对象的语言,采用这种语言进行编程称为面向对象编程(Object-Oriented Programming,OOP)
面向对象编程的本质就是:以类的方式组织代码,以对象的方式组织(封装)数据。
总的来说:面向对象是将事物高度抽象化,面向对象必须先建立抽象模型,然后对模型进行调用
抽象(abstract)
- 忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用关注细节。
- 列如:要设计一个学生体质检测管理系统,那么对于学生,只关心他的体重,身高,视力等,而不用去关心他的成绩,排名这些信息。
抽象就是将多个物体的共同点归纳出来,就是抽出像的部分。
封装(Encapsulation)
- 封装是面向对象的特征之一,是对象和类概念的主要特性。封装是把过程和数据包围起来,对数据进行访问需要通过指定的方式。
- 在定义一个对象的特性时,必须要决定这些特性的可见性,即哪些特性对外部是可见的,哪些特性用于表示内部状态。
- 通常,直接访问一个对象中的数据是被禁止的,而是通过其他操作接口来访问,这称为信息隐藏。信息隐藏是用户对封装性的认识,封装则为信息隐藏提供技术支持。
- 封装不仅保证了模块具有较好的独立性,而且还使得程序维护修改较为容易。对应用程序的修改仅限于类的内部,因而可以将应用程序修改带来的影响减少到最低限度。
继承(inheritance)
- 继承是一种联结类的层次模型,并且允许和支持类的重用,它提供了一种明确表述共性的方法。
- 新类继承了原始类后,新类就继承了原始类的特性,新类称为原始类的派生类(子类),而原始类被称为新类的基类(父亲)。
- 派生类(子类)可以从它的基类(父类)那里继承方法和实例变量,并且派生类(子类)中可以修改或增加新的方法使之更适合特殊的需要继承性很好的解决了软件的可重用性问题。
多态(polymorphism)
- 多态性是指允许不同类型的对象对同一消息做出响应。
- 多态性语言具有灵活、抽像、行为共享、代码共享的优势,很好的解决了应用程序函数同名问题。
相同类域的不同对象,调用相同方法,表现出不同的结果
从认识论角度看,是先有对象后有类。对象,是具体的事物。类,是抽象的,是从对象中抽离出来的特征集合。
从代码运行角度来看,是先有类后有对象。类是对象的模板。
类与对象的关系
类是一种抽象的数据类型,它是对某一类事物整体描述/定义,但是并不能代表某一个具体的事物。
列如:我们生活中所说的词语:动物、植物、电视、电脑、手机等等。这些也都是抽象的概念,而不是指某一个具体的东西,而是指具有某些相同特征事物的总称。
对象是抽象概念(类)的具体实例
例子:
Hero a = new Hero("man","Iron Man");
a.go();
Animal b = new Animal("China","panda");
b.eat();
对象a就是Hero类的一个实例,对象b就是Animal类的一个具体实例,能够使用的是具体的实例,而不是类。类只是给对象的创建提供了一个参考的模板而已。
java中,没有类就没有对象,是先有类才能实例化对象。类是根据具体的功能需求,进行实际的分析,最终抽象出来的。
对象和引用的关系
引用“指向”对象
使用类类型、数组类型、接口类型声明出的变量,都可以指向对象,这种变量就是引用类型变量,简称引用。
在程序中,创建出对象后,直接使用并不方便,所以一般会用一个引用类型的变量去接收这个对象,这个就是所说的引用指向对象。
引用可以“指向”多个对象,但同一时间只能“指向”一个对象。一个对象可以被多个引用同时“指向”。
类中方法的调用
- 同一个类中的两个方法,都是非静态的方法,是可以相互之间直接调用。(非静态方法之间可以相互调用)
public class item{
public void a(){
b();
}
public void b(){
}
}
- a和b都是静态方法,相互之间可以直接调用(静态方法之间可以相互调用)
public class item{
public static void a(){
b();
}
public static void b(){
}
}
- a静态方法,b是非静态方法,a方法中不能直接调用b方法,但是b方法可以直接调用a方法(静态方法不能掉用非静态方法,非静态方法可以调用静态方法)
- 同一个类中,静态方法内不能直接访问到类中的非静态属性
总结:类中方法的调用,两个方法都是静态或者非静态是可以相互调用的。当一个方法是静态,一个方法是非静态的时候,非静态方法可以调用静态方法,反之不能。
调用方法时的值传递与引用传递(此处不过多讨论)
调用方法进行传参时,分为值传递和引用传递两种。
- 如果参数的类型是基本数据类型,那么就是值传递。
- 如果参数的类型是引用数据类型,那么就是引用传递。
- 值传递是实参把自己变量本身存的简单数值赋值给形参.
- 引用传递是实参把自己变量本身存的对象内存地址值赋值给形参. 所以值传递和引用传递本质上是一回事,只不过传递的东西的意义不同而已.
this关键字
在类中,可以使用this关键字表示一些特殊的作用。
this在类中的作用
- 区别成员变量和局部变量
public class Student{
private String name;
public void setName(String name){
//this.name表示类中的属性name
this.name = name;
}
}
- 调用类中的其他方法
public class Student{
private String name;
public void setName(String name){
//this.name表示类中的属性name
this.name = name;
}
public void print(){
//表示调用当前类中的setName
this.setName("tom");
}
}
注:默认情况下,setName(“tom”)和this.setName(“tom”)的效果是一样的。
- 调用类中的其他构造器
public calss Student{
private String name;
public Student(){
//调用一个参数的构造器,并且参数的类型是String
this("tom");
}
public Student(String name){
this.name = name;
}
}
注:this的这种用法,只能在构造器中使用。普通的方法是不能用的。并且这句调用的代码只能出现在构造器中的第一句。
构造方法之间的调用只能通过this语句来完成
构造方法之间进行调用时this语句只能出现在第一行
this关键字在类中的意义
this在类中表示当前类将来要创建出来的对象。
this表示自己这个对象
创建与初始化对象
使用new关键字创建对象
使用new关键字创建时,除了分配内存空间之外,还会给创建好的对象进行默认的初始化以及对类中构造器的调用。
对于main方法中的以下代码:
Student s = new Student();
1)为对象分配内存空间,将对象的实例变量自动初始化默认值为0/false/null。(实例变量的隐式赋值)
2)如果代码中实例变量有显示赋值,那么就将之前的默认值覆盖掉。
如: private String name = "Tom" ;
3)调用构造器
4)把对象的内存地址值赋值给变量(引用)。(=赋值操作)
构造器
类中的构造器也称为构造方法,是在进行创建对象的时候必须要调用的。
构造器的特点:
- 必须和类的名字相同
- 必须没有返回类型,也不能加void修饰
构造器的作用:
- 使用new创建对象的时候必须使用类的构造器
- 构造器中的代码执行后,可以给对象中的属性初始化赋值
public class Student{
private String name;
public Student(){ //构造器(构造方法)
name = "Tom" ;
}
}
构造器重载
除了无参数构造器之外,很多时候会用到有参构造器,在创建对象时可以给属性赋值。
public class Student{
private String name;
public Student(){ //无参构造器
name = "Tom" ;
}
public Student(String name){ //有参构造器
this.name = name ;
}
}
构造器之间的调用
使用this关键字,在一个构造器中可以调用另一个构造器的代码。
注意:this的这种用法不会产生新的对象,只是调用了构造器中的代码而已,一般情况只有使用new关键字才会实例化新对象。
public class Student{
private String name;
private int num;
public Student(String name){ //构造器
this.name = name;
}
public Student(String name,int num){ //构造器
this(name); //构造器之间的调用,只能用this,必须出现在第一句
this.num = num;
}
}
默认构造器
java中,如果我们在编写类的时候没有写构造器,那么在编译之后,也会自动添加一个无参构造器,这个无参构造器也被称为默认的构造器。当时如果我们手动的编写了一个构造器,那么编译过程中就不会添加任何构造器了。
注意
每个类至少要有一个构造函数,如果你自己构建了一个带有参数的构造函数而没有再显示的写出无参的构造函数也是可以的,不过当你尝试通过一个无参的构造函数来构建(new)时,此时编译器才会报错,因为找不到这个无参的构造函数。也就是说当一个类你没有给他构造函数,则编译器会自动补上一个无参的,若有的话就不会,你需要显示将此无参的构造函数写出来
内存分析
栈stack
- 每个线程私有,不能实现线程间的共享!
- 局部变量放置于栈中,存放基本变量类型。
- 栈是由系统内存自动分配,速度快!栈是一个连续的内存空间!
- 引用对象的变量(会存放这个引用在堆里面的具体位置)
堆heap
- 放置new出来的对象!
- 堆是一个不连续的内存空间,分配灵活,速度慢!
- 可以被所有的线程共享,不会存放别的对象引用
方法区(也是堆)
- 被所有线程共享!
- 用来存放程序中永远是不变或唯一的内容。(类代码信息、静态变量、字符串常量)
- 包含所有的class和static变量
引用类型的概念
- java中,除了基本数据类型之外的其他类型称之为引用类型。
- java中的对象是通过引用来操作的。(引用:reference)引用值得就是对象在堆中的地址。
属性(field成员变量)
- 属性用于定义该类或该类对象包含的数据或者说静态属性
- 属性作用范围是整个类体
- 属性的默认初始化
- 在定义成员变量时可以对其初始化,如果不对其初始化,java使用默认值对其进行初始化。
定义格式:
[修饰符] 属性类型 属性名 = [默认值]
public int num = 11;
类的方法
方法是类和对象动态行为特征的抽象。方法很类似于面向过程中的函数。面向过程中,函数是最基本的单位,整个程序由一个个函数调用组成;面向对象中,整个程序的基本单位是类,方法是从属于类或对象的。
方法定义格式:
[修饰符] 方法返回值类型 方法名(形参列表){
// n条语句
}
public int fun(int num){
. . .
return 12;
}
java对象的创建和使用
- 必须使用new关键字创建对象。(String…例外)
Student student = new Student();
- 使用对象(引用),成员变量来引用对象的成员变量
student.age
- 使用对象.方法(参数列表)来调用对象的方法。
student.setAge(25)
类中就是:静态的属性数据,动态的行为方法