类和对象

第1节 类和对象

1.1 认识类和对象

1.1.1 什么是面向对象

传统的开发程序的方式采用过程化的编程方式,即将程序考虑成一个顺序执行的指令串。因此采用过程化开发方式的程序员首先要作的事,就是针对需求,自顶向下、逐步细化,将问题分解成一连串的简单步骤。可是随着用户需求的不断增长和变动,软件规模愈来愈大,业务逻辑愈来愈复杂,传统的这种面向过程的开发方式暴露出来许多问题,如软件开发延迟,开发成本难以控制,工程难以维护等。java

在面向对象程序设计里,将数据和处理数据的方法紧密地结合在一块儿,造成类,再将类实例化,造成对象。计算机程序被概念化成协同工做、共同完成所需任务的一组对象集。每个对象都是程序的一个独立部分,可自行控制并与其余对象进行通讯和交互。程序员

1.1.2 什么是对象

对象,是理解面向对象技术的关键。在现实世界中,对象随处可见,如宠物狗,桌子,自行车,树、鸟、鱼等。真实世界对象具备共同的两个特性:它们都有状态和行为。狗有状态(名字,颜色,品种,饥饿)和行为(叫,刨地,摇尾巴),自行车也有状态(当前的齿轮档位,当前的速度)和行为(变速,刹车)。编程

软件中的对象在概念性上与真实世界中的对象很类似,它们都包括状态和相关的行为。一个对象在属性(在一些程序设计语言中用变量表明)中存储它的状态,并经过方法(在一些程序设计语言中是函数)暴露它的行为。函数

1.1.3 什么是类

在现实世界中,会常常发现许多单独的对象都是同一类型。例如,也许有成千上万的单个的自行车存在,但它们都是一样的模型,以相同的方式被制造。每个自行车都是构建于同一模板并所以包含一样的组件。在面向对象术语中,就能够说,某我的的具体的自行车是自行车这个对象类的一个实例。this

一个类就是一个模板,从它那里个体对象被建立。由类构造对象的过程称为建立类的实例。设计

类是一组具备相同属性和行为的对象的抽象。而对象则是类的具体存在。因此,在面向对象的程序设计语言中,类表明一个对象类型,它就像一个模板同样,在代码运行阶段它被建立为一个个对象实例。每一个类由两个部分组成:属性和行为。属性一般是一些数据状态值,类一般将数据封装在本身内部,访问这些数据属性必须经过类公开的方法,或者接口。code

类的本质是一种自定义的数据类型,可使用类来定义变量,全部使用类定义的变量都是引用变量,它们将会引用到类的对象。对象

1.2 类和对象的建立

1.2.1 如何声明类

对于一个类而言,能够包含三种最多见的成员:Field、方法和构造器。Field用于定义该类或该类的实例所包含的状态数据;方法则用于定义该类或该类的实例的行为特征或者功能实现;构造器用于构造该类的实例。blog

类的声明如如下代码所示:递归

[类修饰符] class 类的名称 [extends 父类名称] [implements 接口名称] {
    //属性、构造函数和方法声明
}

其中class关键字是必需的。类的名称用来标识一个类,它的命名要符合Java标识符命名规范。在这里,用方括号将类修饰符包围起来,它表明的含义是里面的内容是可选的。

在同一个Java源文件中能够有多个类,但不能包含两个或两个以上的带有public修饰词的类。若是某个类的声明前含有public修饰词,那么含有此类的源文件必须与此类的类名相同。

在声明一个类时,还能够提供更多的信息。例如,指明该类的父类(也称为超类)的名称,即该类是从哪一个类派生过来的,这须要在类名后面加上关键字extends来实现。还能够在声明一个类时指明该类是否实现接口,这须要在类名后面加上关键字implements来实现。

类的主体简称类体,指的是类名后面大括号中的内容。类体包含全部用于建立自该类的对象的生命周期的代码,包括构造器(用于初始化新对象)、属性声明(用于表示类及其对象的状态)及方法(实现类及其对象的行为)。

1.2.2 如何建立对象

使用new关键字建立对象。

public class Hello{

    public static void main(String[] args) {
        Hello h1 = new Hello();//建立Hello类的第一个对象
        h.sayWorld();
        Hello h2 = new Hello();//建立Hello类的第二个对象
        h.sayWorld();
    }

    public void sayWorld(){
        System.out.println("Hello world!");
    }
}

一个类能够有多个对象。若是建立了多个对象,则每一个对象都独立的拥有一套类的属性(非static修饰的),意味着,若是咱们修改一个对象的属性a,则不影响另一个对象属性a的值。

1.3 类的成员之一:属性

属性的经常使用叫法:属性=成员变量=field=域=字段。

1.3.1 属性变量的做用域

在程序中有多种类型的变量,这些变量在程序中的位置不一样,所起的做用也不相同。

分类以下:

1.3.2 属性变量的特色

参数和局部变量都是演草纸,方法执行完就清除了。

方法里建立的对象是不会随着方法结束被清除的。由于对象是实例,不是变量,对象被建立出来之后,被堆在一块儿,放在相似公告板的地方,只要有引用指向一个对象,这个对象的数据就能够经过这个引用来访问。

成员变量在类加载时会有初始化值,局部变量在类加载时不会有初始化值,因此因此要使用局部变量时,必定要显式的给它赋值。

1.4 类的成员之二:方法

方法的经常使用叫法:方法=成员方法=函数=method。

1.4.1 什么是方法

所谓方法,相似于其余语言中的函数,是一个相对独立的代码语句块,一般实现必定的功能。

方法的设计原则:方法的本意是功能块,就是实现某个功能的语句块的集合,咱们设计方法的时候,最好保持方法的原子性,就是一个方法只完成一个功能,这样利于咱们后期的扩展

1.4.2 如何定义方法

在类中声明成员方法的语法格式以下:

[修饰符] 方法返回值类型 方法名(形参列表)
{
    //由零条到多条可执行性语句组成的方法体
}
  • 修饰符:修饰符能够省略;
  • 方法返回值类型:返回值类型能够是Java语言容许的任何数据类型,包括基本类型和引用类型;
  • 方法名:方法名只要是一个合法的标识符便可;
  • 形参列表:形参列表用于定义该方法能够接受的参数。一旦在定义方法时指定了形参列表,则调用该方法时必须传入对应的参数值——谁调用方法,谁负责为形参赋值;
  • 方法体里是零条或多条可执行性语句。

1.2.3 方法的四种类型

一、无参数无返回值的方法

// 无参数无返回值的方法(若是方法没有返回值,不能不写,必须写void,表示没有返回值)
public void f1() {
    System.out.println("无参数无返回值的方法");
}

二、有参数无返回值的方法

/**
* 有参数无返回值的方法
* 参数列表由零组到多组“参数类型+形参名”组合而成,多组参数之间以英文逗号(,)隔开,形参类型和形参名之间以英文空格隔开
*/
public void f2(int a, String b, int c) {
    System.out.println(a + "-->" + b + "-->" + c);
}

三、有返回值无参数的方法

// 有返回值无参数的方法 (返回值能够是任意的类型 ,在函数里面必须有return关键字返回对应的类型)
public int f3() {
    System.out.println("有返回值无参数的方法");
    return 2;
}

四、有返回值有参数的方法

// 有返回值有参数的方法
public int f4(int a, int b) {
    return a * b;
}

五、return在无返回值方法的特殊使用

// return在无返回值方法的特殊使用
public void f5(int a) {
    if (a>10) {
    return;//表示结束所在方法 (f5方法)的执行,下方的输出语句不会执行
}
    System.out.println(a);
}

1.4.4 方法的调用

在同一个类中,方法之间的调用语法以下:

方法名( );

在不一样的类之间,方法之间的调用语法以下:

对象名.函数名(实参列表)//方法调用要有括号,即便没有参数

1.4.5 方法的递归调用

A方法调用B方法,咱们很容易理解。

递归就是A方法调用A方法,就是本身调用本身

利用递归能够用简单的程序来解决一些复杂的问题 ,它一般把一个大型复杂的问题层层转化为一个于原问题类似的规模较小的问题来求解,递归策略只需少许的程序就可描述出解题过程所须要的屡次重复计算,大大的减小了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合。

递归结构包括两个部分:

  • 递归头:何时不调用自身方法。若是没有头,将陷入死循环;

  • 递归体:何时须要调用自身方法。

public class Variable {
    public static void main(String[] args) {
        System.out.println(new Variable().f(3));  
    }
    //5! 5*4*3*2*1
    public static int f(int n){
      if(n==1){
          return 1;
      }else {
          return n*f(n-1);
      }
    }
}

1.4.6 方法重载

方法重载指在同一个类里面,有多个名字相同的方法,可是方法的参数类型或者参数的个数不一致,称之为方法重载,方法的返回类型不做为方法重载判断的依据。方法重载以后,具体要调用哪一个重载的方法,由方法的参数类型或个数决定(自动匹配)。

JDK1.5开始,Java支持传递同类型的可变参数给一个方法。

在方法声明中,在指定参数类型后加一个省略号(...)。

一个方法中只能指定一个可变参数,它必须是方法的最后一个参数。任何普通的参数必须在它以前声明。

public class Variable {
    public static void main(String[] args) {
        new Variable().a(1,3,5);
    }

    public void a( int... i){
        System.out.println(i[0]);
    }
}

1.4.7 方法的参数传递

形参,是方法声明时,方法小括号内的参数;实参,是调用方法时,实际传入的参数的值。

那么,Java的实参值是如何传入方法的呢?这是由Java方法的参数传递机制来控制的,Java里方法的参数传递方式只有一种:值传递。所谓值传递,就是将实际参数值的副本(复制品)传入方法内,而参数自己不会受到任何影响。

Java里的参数传递相似于《西游记》里的孙悟空,孙悟空复制了一个假孙悟空,这个假孙悟空具备和孙悟空相同的能力,可除妖或被砍头。但无论这个假孙悟空遇到什么事,真孙悟空不会受到任何影响。与此相似,传入方法的是实际参数值的复制品,无论方法中对这个复制品如何操做,实际参数值自己不会受到任何影响。

可是,当一个对象实例做为一个参数被传递到方法中时,参数的值就是该对象的引用的一个副本。指向同一个对象,对象的内容能够在被调用的方法中改变,但对象的引用(不是引用的副本)是永远不会改变的。也就是说,在方法的执行过程当中,形参和实参的内容相同,指向同一块内存地址,操做的其实都是源数据,因此方法的执行将会影响到实际对象。

1.5 类的成员之三:构造器

1.5.1 声明构造器

类包含有构造器,Java语言经过new关键字来调用构造器,从而返回该类的实例。当建立对象实例时,构造器会被调用以根据类模板建立对象实例。

构造方法是指在一个类里面,方法的名字与类的名字一致,且没有返回值,包括void也没有。简单来讲须要知足两个条件:第一,方法名字和类名一致 ;第二,方法没有任何返回值。构造器是一个特殊的方法。

定义构造器的语法格式以下:

[修饰符] 构造器名(形参列表)
{
    //由零条到多条可执行性语句组成的构造器执行体
}
  • 修饰符:修饰符能够省略;
  • 构造器名:构造器名必须和类名相同。
  • 形参列表:和定义“方法形参列表”的格式彻底相同。

1.5.2 构造器的特色

构造器的声明看上去与方法声明相似,可是构造器有本身的特色。

构造器既不能定义返回值类型,也不能使用void定义构造器没有返回值。实际上,类的构造器是有返回值的,当咱们用new关键字来调用构造器时,构造器返回该类的实例,能够把这个类的实例当成构造器的返回值,所以构造器的返回值类型老是当前类,无须定义返回值类型。但必须注意:不能在构造器里显式使用return来返回当前类的对象,由于构造器的返回值是隐式的。

若是没有显式地添加一个构造方法,Java会给每一个类默认自带一个无参数的构造方法,若是咱们本身添加类的构造方法(不管是否无参),Java就不会再添加无参数的构造方法。这时候,就不能直接new一个对象而不传递参数了。因此咱们一直都在使用构造方法,这也是为何建立对象的时候类名后面要有一个括号的缘由。

1.5.3 构造方法的重载与调用

构造方法的重载和普通方法同样。

构造方法不能被普通方法调用,只能经过new语句在建立对象的时候,间接调用。

只有在构造方法里才能调用重载的构造方法,语法为this+(实参列表),必须是方法的第一行,后面能够继续有代码。

构造方法不能本身调用本身,这是一个死循环。

在调用重载的构造方法时,不可使用成员变量,由于在语意上讲,这个对象尚未被初始化完成,处于中间状态。

1.5.4 this关键字

this关键字老是指向调用该方法的对象。this能够用来修饰属性、方法、构造器。

static修饰的方法中不能使用this引用。若是在static修饰的方法中使用this关键字,则这个关键字就没法指向合适的对象。因此,static修饰的方法中不能使用this引用。

一般状况下,this能够省略,但若是方法的形参和类的属性同名时,不能省略,表示此变量是属性,而非形参。咱们在类的构造器中,能够显式的使用“this(形参列表)”方式,调用本类中指定的其余构造器。但构造器中不能经过“this(形参列表)”方式调用本身。规定“this(形参列表)”必须声明在当前构造器的首行

/***用法有三种:*1.在本类的成员方法中,访问本类的成员变量。
*2.在本类的成员方法中,访问本类的另外一个成员方法。
*3.在本类的构造方法中,访问本类的另外一个构造方法。
*/
public class Zi extends Fu{        
	int num = 20;        
	public Zi(){        
		this(134); //本类的无参构造,调用本类的有参构造        
	}        
	public Zi(int n ){        }        
	public Zi(int n, int m ){                    }        
	public void showNum(){           
 		int num = 10;            
		System.out.println(num); //局部变量           
 		System.out.println(this.num); //本类中的成员变量           
 		System.out.println(super.num); //父类中的成员变量       
 	}
}
public class Fu {
    int num =30;
}

1.6 类的成员之四:代码块

1.6.1 认识代码块

代码块的做用是用来初始化类或对象的。代码块只能使用static修饰,分为非静态代码块和静态代码块。

public Hello {
	{
	//代码块
	}
}

1.6.2 使用代码块

代码块是随着类加载或建立对象的时候执行的。非静态代码块每建立一次对象执行一次,静态代码块只能执行一次。

先加载静态代码块,再加载非静态代码块。同等的代码块按前后顺序执行。

相关文章
相关标签/搜索