day01 java学习第一天 类与对象

day01 java 学习第一天 类与对象

一级目录

二级目录

三级目录

1.1 类的概念与定义

  按照面向对象的观点,它分为状态和行为两部分,再加上类名这一部分,有的学者把它定义为三部分:IS,HAS和DOES.具体含义如下:
  IS:说明类的名字及性质,如一个类的父类、修饰符等,这部分被称为类声明。
  HAS:说明这个类有什么特征及属性,这些特征和属性用域变量来表示,统称为成员变量
  DOES:说明这个类可以做什么,即有哪些行为,这些行为用实例方法和类方法描述,这些方法统称为成员方法。
  IS和HAS部分构成了一个类的状态,DOES就是一个类的行为,行为是通过类的成员方法来实现的。

class 类名        //IS
{  成员变量;       //HAS
   成员方法;      //DOES
}

  在Java中,class是生命一个类的关键字,类名是要声明的类的名字,必须是一个合法的Java标识符,习惯上用大写字母开头。
  在一个类中,既有类的修饰符,也有域修饰符(即成员变量和成员方法的修饰符),两者有所不同。

1.2 类的声明

  类声明定义了类的名字以及其他的属性,说明该类是(IS)一个什么样的类。
  1.2.1 类声明的一般形式
    类声明可以包含3个选项:
    ①声明类的修饰符
    ②说明该类的父类
    ③说明该类所实现的接口
    其形式如下:

[类修饰符]class类名称[extends父类名称][implements接口名称列表]
{
  变量定义及初始化;

  方法定义及方法体
}

  1.类修饰符:public,abstract,final,
  如果未声明这些可选的类修饰符,Java编译器将会给出默认值,即指定该类为非public,非abstract,非final类。
  ①public 该关键字声明的类可以在其他任何类中使用。无此关键字时,只能被同一个程序包的其他类使用。

  类的访问控制符public,类的访问控制符只有一个,因此分为含有public和不含访问控制符两种情况。
  (1)含有public。当一个类被声明为public时,它就具有被其他包中的类访问的可能性,只要在程序中指出恰当的位置并使用import语句引入public类,就可以访问和引用这个类。
  (2)不含访问控制符。若一个类没有访问控制符,说明这个类只能被同一个包中的类访问和引用,这种可访问性称为包可访问性。
  下面这段代码是对public的一个展示:

在这里插入代码片

  ②abstract 声明这是一个抽象类,即该类不能被实例化。

  抽象类就是没有具体对象的类,这样的类要在class前面用修饰符abstract加以修饰。由于抽象类是它的所有子类的公共属性的集合,所以使用抽象类的一大优点就是可以充分利用这些公共属性来提高开发和维护程序的效率。抽象类不能创建对象,必须产生其子类,由子类创建对象。

  ③final 声明该类不能被继承,即该类无子类。
  最终类的修饰符final。类继承虽然非常有用,但不能够滥用。一个类被继承后,就有可能用覆盖的方法去修改它,但正确的东西不应该被篡改,为此,Java提供了一个终结篡改的方法:将一个类声明为final类,该类就不能再有子类了。下面是一个带final修饰的类的举例:

在这里插入代码片

  2.说明一个类的父类
  Java中,除Object外,每个类都有父类。Object是Java中唯一没有父类的类,如果某个类没有声明父类,Java就认为它是Object的直接子类,故,所有其它类都是Objectd的直接子类或间接子类,说明一个父类的形式为:

class 类名 extends 父类名{
...   // 类体
}

  extends子句认为是直接继承其后的父类,在extends后只能跟唯一一个父类名,即定义类时使用extends只能实现单继承(注意,接口可以使用extends实现多继承)。

  3.说明一个类所实现的接口
  为了声明一个类要实现的一个或多个接口,可以在类的声明的最后使用implements,并在其后给出由该类实现的接口的名字表,以逗号隔开。
接口可以声明多个方法和变量,但是没有这些方法的具体实现,而且变量只能是常量。

  4.类体
  类体是跟在类声明后面花括号中的实现部分,要定义该类的所有成员变量和成员方法,也可以从它的父类中继承某些变量和方法。

1.3 成员变量的声明

  1.3.1 成员变量声明的一般形式
  声明一个成员变量的一般形式:
  [可访问性修饰符][static][final]类型 变量名;
  上述用方括号[]括起来的部分表示可选项,其含义如下:
  ①可访问性修饰符:说明该变量的可访问属性,即定义该变量的可访问范围。这些修饰符可为public,protected和private。
  ②static:说明该成员变量为类变量,以区分一般的实例变量。类变量是一个类所有的,而不是一个类的每个实例都有的变量。
  ③final:说明一个常量。

  1.3.2 域修饰符(域即成员变量)
  域即成员变量,表示类和对象的特征属性。域修饰符分为域的访问控制符和非访问控制符。
  ①成员变量的访问控制符
  一个类作为整体对程序的其他部分可见,并不代表类中的所有域和方法也同时对程序的其他部分可见。类的域和方法能否为所有其它类访问,还要看内层的访问控制符,即成员变量和成员方法这个层次的访问控制符。
  Java支持对成员变量和方法的4个访问等级:private,protected,public以及默认修饰符(即不指定访问修饰符)。
  下表给出了一个公共类,不同的访问修饰符在不同范围的类和对象是否有权访问他们。

访问修饰符同一个类同包不同包,子类不同包,非子类
private
protected
public
默认(无修饰符)

  一般情况下一个成员只有在外部对象使用后不会产生不良影响时才声明为公共的(public)。
  默认(无访问修饰符),说明使用的就是包访问级。这个访问级别允许在相同的包中的类访问该成员。

  ②类变量修饰符static
  Java类包括2种成员变量:类成员变量和实例成员变量。在声明成员变量时,用static修饰就是类变量,没有static就是实例变量。
  声明实例变量后,每次创建类的一个对象时,系统就会为该对象创建实例变量的副本,即该对象每个实例变量都有自己的存储空间,然后就可以通过对象名访问这些实例变量。
类变量和实例变量的区别是,第一次调用类时,系统仅为类变量分配一次内存,不管该类要创建多少对象,所有对象共享该类的类变量。因而,可以通过类本身或某个对象来访问类变量。
  下面是举的一个例子:
  定义一个AnIntegerNamedX类,将它的成员变量x指定为一个类变量。

class AnIntegerNamedX {
	static int x;   // 使用了static关键字
	public int x() {
		return x;   // 返回x的值
	}
	public void setX(int newX) {
		x = newX;   // 设置x的值
	}
}

  再编写一个类,它包含2种不同AnIntegerNamedX类型的对象,并且将x设置为不同的值,然后显示出来。

public class Compare_test {
	public static void main(String args[]) {
		AnIntegerNamedX myX = new AnIntegerNamedX();
		AnIntegerNamedX anotherX = new AnIntegerNamedX();
		myX.setX(1);
		anotherX.x = 2;
		System.out.println("myX.x = " + myX.x());
		System.out.println("anotherX = " + anotherX.x());
	}
}

  输出结果为:

myX.x = 2
anotherX = 2

  从两个对象中输出x,其结果相同,这是因为x是一个类变量,类变量只存储唯一版本,他被该类的所有对象所共享,包括myx和anotherX.当有任何一个对象中调用setX的时候,也就改变了该类所有对象所共享的x的值。

1.4 变量的作用域

1.5 成员方法的声明与实现

  1.5.1 方法声明的一般形式
  成员方法是类的动态属性。
  方法有两个主要部分:方法首部声明和方法体。方法声明的基本形式:

返回类型 方法名(){
...       //方法体
}

  方法首部的声明包括方法的修饰符,返回类型,方法名,圆括号以及括号内的参数表,方法体中有实现方法行为的Java语句。
  方法声明的一般形式如下:

[可访问性修饰符][abstract][static][final][native][synchronize]
返回类型 方法名(参数表)[throws 异常类名表]{... //方法体}

  1.5.2 方法修饰符
  方法的修饰符也可以分为访问控制符和非访问控制符。成员方法的访问控制符域成员变量的访问控制符的作用和用法几乎是一样的。以下介绍几种常用的非访问控制符修饰的方法。
  (1) 抽象方法
修饰符abstract修饰的抽象方法是一种仅含有方法声明部分,而没有方法体和具体的操作实现部分的方法。例如,下面声明的计费方式的方法charge_Mode()就是抽象类Telephone中定义的一个抽象方法。

abstract void charge_Mode();

为什么在这里不定义方法的实现呢?

  charge_Mode()方法是抽象类Telephone的一个抽象方法,Telephone类是从所有电话中抽象出来的公共属性集合,每种电话都有不同的“计费方式”,都有着不同的操作方法。在抽象类Telephone中定义了charge_Mode()抽象方法,但并没有具体地实现它,想要实现它需要在其子类中去实现,子类继承了父类的各种抽象方法,再用不同的方法体去重新定义charge_Mode()方法,形成了若干名字相同,返回值类型相同,参数列表相同,目的一致,但具体实现有一定差别的方法。

  需要特别注意的是,所有的抽象方法都必须存在于抽象类中。一个非抽象类中出现抽象方法时非法的,但抽象类却不一定只有抽象方法,还可以包括非抽象的方法。另外需要注意的是,一个抽象类的子类如果不是抽象类,则它必须实现父类中的所有抽象,包括父类继承来的抽象方法。
  (2) 类方法与实例方法
  一个类的方法与类的成员变量类似,有实例方法和类方法,用static修饰符修饰的方法是属于整个类的类方法,简称类方法,没有使用static修饰的方法是实例方法,实例方法可以对当前对象实例变量进行操作,而且可以访问类变量。
  声明一个方法为static方法至少有3个概念需要注意:
  ①调用这个方法时,应该使用类名作前缀,而不是使用某一个具体的对象名(尽管有的地方可以使用对象名调用)。
  ②非static的方法是属于某个对象的方法,在创建这个对象时,对象的方法在内存中拥有自己的专用的代码段,而static方法是属于整个类的,它在内存中的代码段随着类的定义而装载,不被任何一个对象单独拥有。
  ③由于static方法是属于整个类的,所以它不能操纵和处理属于某个对象的成员,只能处理属于整个类的成员变量,即static方法只能处理static域。

  类方法
  当一个类被装载时,系统只为该类的类方法创建一个版本,这个版本被该类和该类的所有实例所共享

  举一个类方法的例子,定义一个类AnIntegerNamedX,将他的成员变量x定义为类变量,有x()和setX()两个类方法,通过这两个类方法可以设置和查询x的数值。

class AnIntegerNamedX {
	static int x;    //类变量
	static public int x() {
		return x;   // 返回x的值
	}
	static public void setX(int newX) {
		x = newX;   // 设置x的值
	}
}

  如果上述代码的类变量变成了实例变量,就会报错了,因为类方法不能访问实例变量,除非该方法首先创建类的一个对象,并且通过该对象的实例方法来访问这个实例变量,再或者把这个实例变量改为类变量,如下代码,在运行后就会报错。

class AnIntegerNamedX {
	int x;    //实例变量
	static public int x() {
		return x;   // 返回x的值
	}
	static public void setX(int newX) {
		x = newX;   // 设置x的值
	}
}

  实例成员和类成员之间的另一个不同点是,类成员可用类名来访问,不必通过创建对象来访问类成员,这里的成员可以是成员变量和成员方法。其形式为:类名.类成员名
如,在Compare_test类中可用如下方法直接使用类方法。

AnIntegerNamedX.setX(1);
System.out.println("AnIntegerNamedX.x = " + AnIntegerNamedX.x());

  在这里写一下Compare_test类的代码,避免自己看不懂:

public class Compare_test {
	public static void main(String args[]) {
		AnIntegerNamedX myX = new AnIntegerNamedX();
		AnIntegerNamedX anotherX = new AnIntegerNamedX();
		myX.setX(1);
		anotherX.x = 2;
		System.out.println("myX.x = " + myX.x());
		System.out.println("anotherX = " + anotherX.x());
	}
}

  实例方法
  举一个实例方法的例子,定义一个类AnIntegerNamedX,将他的成员变量x定义为实例变量,有x()和setX()两个实例方法,通过这两个实例方法可以设置和查询x的数值。

class AnIntegerNamedX {
	int x;   //实例变量,没有使用关键字static
	public int x() {
		return x;   // 返回x的值
	}
	public void setX(int newX) {
		x = newX;   // 设置x的值
	}
}

  这时在运行Compare_test类的输出为:

myX.x = 1
anotherX = 2

  类的所有对象共享一个实例方法的相同实现,但各有各的运行环境。
  分析这里的AnIntegerNamedX类和Compare_test类不难看出:
  1.AnIntegerNamedX外部的对象如果想访问x,必须通过AnIntegerNamedX的一个特定实例对象实现。
  2.x() 方法和setX()方法操作的是两个不同的副本:一个包含在myX对象中,另外一个包含在anotherX对象中,这是因为每个对象都有它自己的实例变量x,并且每个实例变量可以有不同的值。

  (3) 最终方法
  由final修饰符修饰的方法就是最终方法。最终方法是不能被当前类的子类重新定义的方法。需要注意的是,所有被private修饰的私有的方法和定义在final类中的方法,都被默认为final的。因为这些方法要么不可能被子类继承,要么根本没有子类。
  在面向对象程序设计中,一般情况下子类可以把从父类那里继承来的某个方法进行改写并重新定义,形成与父类方法同名,求解的问题相似,但具体实现和功能不尽相同的新的方法,这个过程被称为覆盖。但是,如果类的某个方法被final修饰,就只能从父类那里原原本本地继承该方法了。
  (4) 本地方法(现阶段很少用)
  被native修饰的方法就是本地方法,一般是用来生命用其他语言书写方法体的特殊方法,如C++,FORTRAN,汇编语言等,native方法无方法体。当要考虑跨平台性时使用native方法应该特别谨慎。
  (5) 同步方法(现阶段很少用,以后要用时再补充)
  用synchronized修饰的方法是同步方法。

  1.5.3 方法的返回类型
  一个方法必须声明其返回类型,如果无返回值,则必须声明其返回类型为void。一个方法可以返回简单数据类型或任何引用类型的值。
  一个方法通过return语句返回。如果一个方法的返回类型是void,这个方法也可以包含一个return语句,只是在return语句之后不再带有返回值;当return语句带有返回值时,它与方法定义的返回类型必须符合以下几种情况之一:
  ①当方法声明的返回类型是基本数据类型时,返回值得数据类型必须与返回类型一致。
  ②当方法声明的返回类型是一个类时,返回对象的数据类型必须是与方法声明的返回类相同的类或者其子类。
  ③当方法声明的返回类型是一个接口类型时,返回的对象所属的类必须实现这个接口。
  
  返回值必须与返回类型匹配,这是一个基本原则。

  这是java常用数据类型的分类在这里插入图片描述
  1.5.4 方法名
  ①方法的重载
  Java支持方法名重载,即多个方法可以共享一个名字。重载的方法不一定要返回相同的数据类型。
  举一个重载的例子,定义一个重载类,,其中有doubleIt()方法,将输入的数据“加倍”后显示出来。代码如下:

public class OverLoad {
	public static String doubleIt(String data) {
		System.out.println(data + data);
		return data + data;
	}
	public static int doubleIt(int data) {
		System.out.println(2 * data);
		return data + data;
	}
	public static void main(String[] args) {
		System.out.println("Hello World!" + doubleIt("pizza") + doubleIt(66));
	}
}

  其运行结果如下:

pizzapizza
132
Hello World!pizzapizza132

  重载虽然表面上没有减少编写程序的工作量,但实际上使得程序的实现变得简单。我们只需要记住一个方法名,他就可以根据不同类型的输入选择该方法的不同版本。
  ②重载方法的参数必须有所区别
  参数有所区别可以是以下情况之一:
  1.参数的类型不同。
  2.参数的顺序不同。这里指的是一个方法有多个参数的情况。
  3.参数的个数不同。

  1.5.5 方法的参数
  编写一个方法时,一般在方法名之后列出一个参数表来声明该方法所需要的若干参数和这些参数的类型,参数表由各参数的类型及名字组成,各参数间以逗号隔开,在方法体中,可以直接使用这些参数名来引用参数的值。
  ①参数名
  声明一个参数与声明一个变量一样,只是声明的位置必须是在参数表中。一个参数是一个方法的边缘,它与成员变量毫无关系,因此参数名可以和成员变量名相同。如果一个方法的参数名与成员变量名同名,则在这个方法中,参数隐藏了这个成员变量名,即,在方法中出现的这个名字指的是参数名,而不是成员变量。隐藏成员变量的参数常常用于构造方法(与类同名的方法)中初始化一个类。
  下面这个例子来说明参数名和成员变量名相同的情况:

public class Circle {
	int x,y,radius;
	public Circle(int x,int y,int radius) {
		...
	}
}

  这个Circle类有3各成员变量,x,y,radius.在类的构造方法中有3个参数,名字也是x,y,radius。那么在方法体中出现的x,y,radius指的是参数名。如果要访问这些同名的成员变量,必须通过“当前对象”指示符this来引用他,代码如下:

public class Circle {
	int x,y,radius;
	public Circle(int x,int y,int radius) {
		this.x = x;
		this.y = y;
		this.radius = radius;
	}
}

  ②参数的类型
  在Java中,可以把任何有效数据类型的参数传递到方法中。对参数的处理,Java与其他语言的不同之处是:Java不允许把方法作为参数传递到方法中。但有一个变通的办法:将对象作为参数,然后再调用这个对象的方法。

  1.5.6 方法的参数传递(这部分我还没看懂,日后在多看几遍吧,有了解的同志可以评论告诉我呀)
  对调用方法时输入该方法的参数,要明确如下概念:
  (1)调用不带参数的方法是在方法名后加一对空括号。
  (2)调用带参数方法是在方法名后面的括号中加入一组与输入参数类型相同或兼容的表达式,表达式间以逗号隔开。
  (3)Java的参数传递方式时传递值(值传递),对值传递方式要区分2种情况:
  ①当参数变元是一个简单类型时,值传递意味这这个方法不能改变参数变元的值,即方法中的变量所做的改变在方法外都是不可见的,也可以说是不起作用的。(个人认为就相当于python中的可变数据类型)。
  ②当参数变元是一个引用类型时,值传递意味着这个方法不能改动这个对象的引用(指针),但可以通过方法调用该对象的方法来修改该对象中的可访问的变量。(个人认为就相当于python中的不可变数据类型)。
  何时是引用变量本身的值发生改变,何时使其指向的数据发生改变呢?
  如果引用变量在赋值号左边,则它的值的改变在外部是不可见的。
如果使用引用变量访问所指向的数据,则只要引用变量所指向的数据发生改变,这种改变是外部可见的。
  1.5.7 方法体
  在一个方法体中除了有实现方法的功能的基本语句外,还要注意下述变量的使用:
  (1)null变量
  (2)this变量
  (3)supper变量
  (4)局部变量

1.6 对象的创建与撤销

  定义了一个新的类之后,接下来就可以创建这个类的一个对象,对象是以类为模板船舰的具体实例,要创建对象就要使用构造方法。
  1.6.1 定义和使用构造方法
  所有的Java类都有构造方法,构造方法是与类同名的方法。船舰对象的语句用new运算符开辟了新建对象的内存空间之后,将调用构造方法初始化这个创建对象。
构造方法的形式为:

[public]类名(参数表){...}

  构造方法是类的一种特殊方法,它的特殊性体现在如下方面:
  ①构造方法的方法名与类名相同。
  ②构造方法没有返回类型。
  ③构造方法不能被static,final,abstract,synchronized,native等修饰符修饰。
  ④构造方法不能像一般方法那样用“对象.”显式的直接调用,应该用new关键字构造方法为新对象初始化。

1.7 类的进一步说明

  再写一下定义类的整体视图.

[public|abstract|final]class 类名称[extends 父类名称][implements]{
[可访问性修饰符][static][final]类型 变量名;

[可访问性修饰符][abstract][static][final][native][synchronize]
        返回类型 方法名(参数表)[throws 异常类名表]{... // 方法体}
}

  定义一个类,主要讨论的是类及其成员的修饰符。修饰符分为访问控制符和非访问控制符。修饰符修饰的对象分为两个层次:①类层次②类内部成员变量及成员方法层次。

  类的访问控制符只有public。域和方法的访问控制符有public,private,protected和默认情况(不使用任何访问控制符)。
  访问控制符小结:
  (1)公共访问控制符(public):
  ①public类:公共类,可被其他包中的类引入后访问
  ②public方法:是类的接口,用于定义类中对外可用的功能方法
   ③public域:可被所有访问该类的类访问
   (2)默认访问控制符的类,域和方法:具有包访问性(只能被同一个包中的类访问)
  (3)私有访问控制符(private):修饰域或方法,只能被该类自身访问
  (4)保护访问控制符(protected):修饰域或方法,可被类自身,同一个包中的类,任意包中该类的子类访问。
  非访问控制符,最常用的有static,final和abstract。

1.8 程序包

  本文主要来自面向对象与java程序设计(第三版),个人觉得书上的东西太繁琐,有些东西在现阶段自己尚且理解不了,有所省略,写下来这个的目的只是带领自己温习课本知识,加深自己对课本的理解,没有写完的部分改天再续。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值