06 Java语言核心知识 - 8

面向对象设计——类和对象

1 面向对象程序设计的基本概念

面向对象其实是现实世界模型的自然延伸。可以将现实世界中的任何实体看作是对象,对象之间通过消息相互作用。另外,现实世界中的任何实体都可归属于某类事物,任何对象都是某一类事物的实例。传统的过程式编程语言是以过程为中心、以算法为驱动的话,面向对象的编程语言是以对象为中心、以消息为驱动。公式表示,过程式编程语言为:程序 = 算法 + 数据,面向对象编程语言为:程序=对象+消息。
所有面向对象编程语言都支持3个概念,即封装、多态性和继承。现实世界中的对象均有属性和行为,映射到计算机程序上,属性则表示对象的数据,行为表示对象的方法(其作用是处理数据或同外界交互)。所谓封装,就是用一个自主式框架把对象的数据和方法连在一起形成一个整体。可以说,对象是支持封装的手段,是封装的基本单位。类描述了一组有相同特性(属性)和相同行为(方法)的对象。在程序中,类实际上就是数据类型,例如整数、小数等。整数也有一组特性和行为。面向过程的语言与面向对象的语言区别在于,面向过程的语言,不允许自己定义数据类型,只能使用程序中内置的数据类型。而为了模拟真实世界,为了更好的解决问题,我们往往需要创建解决问题所必须的数据类型。

1.1 对象

对象的特征分为静态特征和动态特征。静态特征指对象的外观、性质、属性等,动态特征指对象具有的功能、行为等。
一般,将静态特征抽象为属性,在Java中称之为变量;将对象的动态特征抽象为行为,用一组代码表示,完成对数据的操作,在Java中称之为方法。一个对象是由一组属性和一组对属性进行操作的方法构成。

1.2 类

将具有相同属性及相同行为的一组对象称之为类。广义上讲,具有共同性质的事务的集合称之为类。

在面向对象的设计中,类是一个独立的单元,他有一个类名,其内部包括成员变量,用于描述对象的属性;还包括类的成员方法,用于描述对象的行为。在Java程序设计中,类被认为是一种抽象的数据类型,这种数据类型不但包括数据,还包括方法,这大大地扩充了数据类型的概念。

类是一个抽象的概念,要利用类的方式来解决问题,必须用类创建一个实例化的类对象,然后通过类对象去访问类的成员变量,去调用类的成员方法来实现程序的功能。就如同 汽车 本身是一个抽象概念,只有使用了一辆具体的汽车,才能感受到汽车的功能。

一个类可创建多个类对象,它们具有相同的属性模式,但可以具有不同的属性值。Java程序为每一个类对象都开辟了内存空间,以便保存各自的属性值。

面向对象的程序设计有以下3个主要特征:

  • 封装性
  • 继承性
  • 多态性

1.3 封装性

封装性将尽可能对外界公布一个有限的界面,而将其细节隐藏起来,与其他对象的交往通过这个界面进行。这就是我们常说的信息隐藏性。

一个公司(或企业)的经营活动可以理解为一个 封装性 的概念。该公司的基本活动可以由各部门(基本数据)和调度部门(对此数据操作的过程)或共同完成的产品(函数)结合起来。各部门之间的(外界)联系是由公司总调度(或领导)和各部门调度(或部门领导)实现的。

封装 性的概念可以从以下3个方面理解
(1)所以软件的内部都应有明确的范围、清楚的外部边界,这就像公司的各部门有明确的职责范围、各部门之间有确定的权限一样。
(2)每个软件部件都应具有友好的界面或接口,以表明软件部件之间的相互作用和相互联系,这就像公司的各部门相互间的衔接工序和各部门之间有联系与制约一样。
(3)完成、保护和隐藏软件的内部实现,用户不必了解其具体的实现,这就像一个工厂的各个车间生产不同的零部件,本车间完成自己的工作,对外提供成品零部件,使用零部件者不必知道其生产过程一样。

有了封装性,软件设计人员就可以集中精力考虑开发系统各模块之间的关系等重大问题,而模块内部的实现则可由程序设计人员研究与完善,这样可以充分保证模块的质量和可靠性,也支持软件工程化思想。

1.4 继承性

如果类 B 具有类 A 的全部属性和方法,而且又具有自己特有的某些属性和方法,则把类 A 称作一般类,而把类 B 称做特殊类。

在面向对象程序设计中运用继承原则,就是在每个由一般类和特殊类形成的一般——特殊类结构中,把一般类的对象实例和所有特殊类的对象实例都共同具有属性和操作一次性地在一般类中进行显式的定义,在特殊类中不再重复地定义一般类中已经定义的东西,但是在语义上,特殊类却会自动地、隐含地拥有它的一般类(以及所有更上层的一般类)中定义的属性和操作。

特殊类的对象拥有其一般类的全部或部分属性与方法,称做特殊类对一般类的继承。

继承所表达的就是一种对象之间的相交关系,它使得某类对象可以继承另外一类对象的数据成员和成员方法。

若类 B 继承类 A ,则属于B的对象便具有类A的全部或部分性质(数据属性)和功能(操作)。

我们称被继承的类 A 为基类、父类或超类,而称继承类 B 为 A 的派生类或子类。继承避免了对一般类和特殊类之间共同特征进行的重复描述。

继承具有以下特征:
(1)继承关系是传递的。继承是在一些比较一般的类的基础上构造、建立和扩充新类的最有效的手段。
(2)继承简化了人们对事物的认识和描述,能清晰体现相关类间的层次结构关系。
(3)提供了软件复用功能。
(4)通过增强一致性来减少模块间的接口和界面,大大增加程序的易维护性。
(5)提供多重继承机制。从理论上说,一个类可以是多个一般类

1.5 多态类

多态是面向对象程序设计的又一个重要特征。多态是允许程序中出现重名现象。Java语言中含有方法重载与成员覆写两种形式的多态。

方法重载:在一个类中,允许多个方法使用同一个名字,但方法的参数不同,完成的功能也不同。

成员覆写:子类与父类允许具有相同的变量名称,数据类型不同,允许具有相同的方法名称,但完成的功能不同。
多态的特性使程序的抽象程度和简捷程度更高,有助于程序设计人员对程序的分组协同开发。

2 类

类(class)和对象(object)就是面向对象方法的核心概念。类是对某一类事物的描述,是抽象的、概念上的定义;对象是实际存在的该类事物的个体,因而也称做实例(Instance)。
在这里插入图片描述
图中汽车设计图就是 ,由这个图纸设计出来的若干的汽车就是按照该类产生的 对象 。可见,类描述了对象的属性和对象的行为,类是对象的模板。对象是类的实例,是一个实实在在的个体,一个类可以对应多个对象。可见,如果将对象比做汽车,那么类就是汽车的设计图纸,所以面向对象程序设计的重点是类的设计,而不是对象的设计。
同一个类按同种方法产生出来的多个对象,其开始的状态都是一样的,但是修改其中一个对象的时候,其他的对象是不会受到影响的,比如修改第1辆汽车的时候,其他的汽车是不会受到影响的。

2.1 类的声明

使用类之前,必须先声明它,然后才可利用所声明的类来声明变量,并创建对象。类声明的语法如下:

class 类名称
{
	类的成员变量
	类的方法
}

可以看到,声明类使用的是class关键字。声明一个类时,在class关键字后面加上类的名称,这样就创建了一个类,然后在类的里面定义成员变量和方法。
举一个Person的例子,以使读者清楚地认识类的组成。

class Person
{
	String name;
	int age;
	void talk()
	{
		System.out.println("我是:"+name+",今年:"+age+"岁");
	}
}

【代码解析】
程序首先用class声明了一个名为Person的类,在这里Person是类的名称。
第3、4行先声明了两个属性name和age,name为String型,age为int型。
第5~8行声明了一个talk( )方法,此方法用于向屏幕打印信息。
为了更好的说明类的关系,请看下图:
Person
提示:
声明类Person时,类名中单词的首字母是大写,
这是规定的一种符合标准的写法。

2.2 类的定义

在声明一个类后,还需要对类进行定义,定义一个类后就定义了一个功能模块。定义类的语法如下。

class 类名称
{
	数据类型 属性;

	返回值的数据类型 方法名称(参数1,参数2,···)
	{
		程序语句 ;
		return 表达式 ;
	}
}

定义一个类后,就可以创建类的实例了,创建类实例通过new关键字完成。下面通过一个实例讲解如何定义并使用类。

class colordefine{
	String color="黑色";
	
	void getMes(){
		System.out.println("定义类");
	}
	
	public static void main(String args[]){
		colordefine b = new colordefine();	   //创建类实例通过new关键字完成
		System.out.println(b.color);		   //属性调用
		b.getMes();							   //子函数的调用
	}
}

# 程序运行结果:
黑色
定义类

3 对象

3.1 对象的声明

由类产生的基本形式:

类名 对象名 = new 类名();

举例:
import java.util.Scanner;
Scanner input = new Scanner(System.in);

创建属于某类的对象,需要通过下面两个步骤实现。
(1)声明指向 由类所创建的对象 的变量。
(2)利用new创建新的对象,并指派给先前所创建的变量。

举例:如果要创建Person类的对象,可用下列语句来实现

Person p ; 					// 先声明一个Person类的对象p
p = new Person();			// 用new关键字实例化Person的对象p

# 另一种形式
Person p = new Person();  // 声明Person对象p并直接实例化此对象

提示:
对象只有在实例化之后才能被使用,而实例化对象的关键字就是new。

在这里插入图片描述
如上图所示,当语句执行到Person p时,只是在栈内存中声明了一个Person的对象p,但是这个时候p并没有在堆内存中开辟空间,所以这个时候的p是一个未实例化的对象,用new关键字实际上就是开辟堆内存,把堆内存的引用赋予p,这个时候的p才称为一个实例化对象。

3.2 对象的使用

如果要访问对象里的某个成员变量或方法,可以通过下面的语法来实现。

访问属性:对象名称.属性名;
访问方法:对象名称.方法名();

# 例如想访问Person类中的name和age属性,可以用如下方法来访问。
p.name;			// 访问Person类中的name属性
p.age;			// 访问Person类中的age属性

# 若想将Person类的对象p中的属性name赋值给"张三",年龄赋值为25,
# 则可采取下面的写法。
p.name = "张三";
p.age = 25;

# 如果想调用Person中的talk()方法,可以采用下面的写法。
p.talk();			//调用Person类中的talk()方法

# 下面是完整的程序
class Person{
	String name;
	int age;
	void talk(){
		System.out.println("我是:"+name+",今年"+age+"岁");
	}
}

使用Person类的对象调用类中的属性与方法的过程

下面这个范例说明了使用Person类的对象调用类中的属性与方法的过程
class TestPersonDemo{
	public static void main(String[] args){
		Person p = new Person();
		p.name = "张三";
		p.age = 25;
		p.talk();
	}
}

# 运行结果:
我是:张三,今年:25

第4行声明了一个Person类的实例对象p,并直接实例化此对象。
第5、6行对p对象中的属性赋值。
第7行调用talk()方法,在屏幕上输出信息。
在这里插入图片描述

3.3 对象的比较

有两种方式可用于对象间的比较,即 “ == ” 运算符与equals()方法。
“ == ” 运算符用于比较两个对象的内存地址值是否相等,equals()方法用于比较两个对象的内容是否一致。

public class TestEquals{
	public static void main{
		String str1 = new String("java");
		String str2 = new String("java");
		String str3 = str2;
		if (str1==str2) {
			System.out.println("str1==str2");
		} else {
			System.out.println("str1!=str2");
		}
		if (str2==str3) {
			System.out.println("str2==str3");
		} else {
			System.out.println("str2!=str3");
		}
	}
}

# 运行结果:
str1 != str2
str2 == str3

用" == "比较的是内存空间
str1和str2是分别实例化了String类的两个对象,此时,这两个对象指向不同的内存空间,所以它们的内存地址是不一样的。这个时候程序中是用的" == "比较,比较的是内存地址值,所以输出str1 != str2。
str3 = str2 str2引用赋值给str3,这时候就相当于str3也指向了str2的引用,此时这两个对象指向的是同一内存地址,所以比较的结果是str2==str3。
用equals方法用于对象比较:

public class TestEquals1{
	public static void main(String[] args){
		String str1 = new String("java");
		String str2 = new String("java");
		String str3 = str2;
		if (str1.equals(str2)) {
			System.out.println("str1 equals str2");
		} else {
			System.out.println("str1 not equals str2");
		}
		if (str2.equals(str3)) {
			System.out.println("str2 equals str3");
		} else {
			System.out.println("str2 not equals str3");
		}
	}
}

# 运行结果:
str1 equals str2
str2 equals str3

在程序中将比较的方式换成了equals()的方法的是String类的对象,所以可以知道equals是String类中的方法。" == " 是比较内存地址值的,而 " equals " 是比较内容的。

3.4 对象数组的使用

对象也可以用数组来存放,可通过下面两个步骤实现:
(1)声明类类型的数组变量,并用new分配内存空间给数组;
(2)用new产生新的对象,并分配内存空间给它。

Person p[];				// 声明Person类类型的数组变量
p = new Person[3];		// 用new分配内存空间

创建好数组元素之后,便可把数组元素指向由Person类所产生的对象。

p[0] = new Person();
p[1] = new Person();
p[2] = new Person();

此时,p[0]、p[1]、p[2]是属于Person类类型的变量,他们分别指向新建对象的内存参考地址。当然也可以写成如下形式。

Person p[]= new Person[3];		// 创建对象数组元素,并分配内存空间

也可以利用for循环来完成对象数组内的初始化操作,此方式属于动态初始化。

for(int i=0;i<p.length;i++){
	p[i] = new Person();
}

或者采用静态方式初始化对象数组。

Person p[] = {new Person(),new Person(),new Person()};

用静态方式初始化对象数组

class Person{
	String name;
	int age;
	
	public Person(){
	}
	
	public Person(String name, int age){
		this.name = name;
		this.age = age;
	}
	
	public String talk(){
		return "我是:"+this.name+",今年:"+this.age+"岁";
	}
}

public class TestObjectArray{
	public static void main(String[] args){
		Person p[]={new Person("张三",25),
					new Person("李四",30),
					new Person("王五",35)};	
		//用静态声明方式声明了3个对象的Person类的对象数组。
		
		for(int i=0;i<p.length;i++){
			System.out.println(p[i].talk());
		//用for循环输出所有对象,并分别调用talk()方法打印信息。
		}
	}
}

# 运行结果
我是:张三,今年:25岁
我是:李四,今年:30岁
我是:王五,今年:35

4 类的属性

类的基本组成包含属性和方法。先来讲解属性,类的属性也成为字段或成员变量,不过习惯上将它称为属性。

4.1 属性的定义

[public|protected|private|default] 
		[(static [final])|(final [static])] className prorotypeName

下面有些方法是错误的。

public class A{public class B{public static String_str;}}
错误,非静态内部类不能定义静态属性
public class A{public class B{public static final String_str;}}
正确,非静态内部类可以定义静态常量属性
public class A{public class B{public static void Method(){}}}
错误,非静态内部类不能定义静态方法
public class A{public class B{public static class C{}}}
错误,非静态内部类不能定义静态内部类

public class A{public static class B{public static void method(){}}}
正确,静态内部类可以定义静态方法
public class A{public static class B{public void method(){}}}
正确,静态内部类可以定义非静态方法
public class A{public static class B{public static String_str;}}
正确,静态内部类可以定义静态属性
public class A{public static class B{public class C{}}}
正确,静态内部类可以定义非静态内部类
public class A{public static class B{public static class C{}}}
正确,静态内部类可以定义静态内部类

总结:
非静态内部类 只能定义静态常量属性,不能定义静态方法、静态属性、静态内部类;
静态内部类 可以定义静态方法、静态属性、静态内部类、非静态方法、非静态内部类

public class A{public class B{}}		非静态内部类

static 			静态
String_str		属性
final			常量
void Method(){}	静态方法
class C{}		非静态内部类

类的属性定义规则如下:
(1)类的属性是变量;
(2)类的属性的类型可以是基本类型,也可以是引用类型;
(3)类的属性的命名规则,首单词的首字母小写,其余单词的首字母大写。
类变量和成员变量的区别在于:类变量就是 static 修饰的变量,它们被类的实例所共享,就是说一个实例改变了这个值,其他的实例也会受到影响;成员变量则是实例所私有的,只有实例本身可以改变它的值。

4.2 属性的使用

类属性组的使用

public class Test{

	static String a="string-a";
	static String b;
	
	String c = "string-c";
	String d;

	static{
		printStatic("before static");
		b = "string-b";
		printStatic("after static");
	}

	public static void printStatic(String title){
		System.out.println("--------" + title + "--------");
		System.out.println("a=\"" + a + "\"");
		System.out.println("b=\"" + b + "\"");
	}

	public Test(){
		print("before constructor");
		d = "string-d";
		print("after constructor");
	}

	public void print(String title){
		System.out.println("--------" + title + "--------");
		System.out.println("a=\"" + a + "\"");
		System.out.println("b=\"" + b + "\"");
		System.out.println("c=\"" + c + "\"");
		System.out.println("d=\"" + d + "\"");
	}

	public static void main(String[] args){
		new Test();
	}
}

运行结果
在这里插入图片描述
Java类属性和对象属性的初始化顺序如下:
(1)类属性(静态变量)定义时的初始化,如范例中的static String a=“string-a”。
(2)static块中的初始化代码,如范例中的static{}中的b=“string-b”。
(3)对象属性(非静态变量)定义时的初始化,如范例中的String c=“string-c”。
(4)构造方法(函数)中的初始化代码,如范例构造方法中的d=“string-d”。

5 类的方法

类的方法是类的任一个特定实例都能调用的方法,作用范围是整个类,而不是类的某个特定实例。类方法也称做静态方法,在类中定义的方法叫做该类的成员。

5.1 方法的定义

所有的方法均在类中声明。定义方法的一般形式如下:

type name(参数列表){
	方法主体 
}

① type指定了由方法返回的数据类型。它可以是任意有效的类型,包括创建的类类型。如果方法没有返回值,则其返回值类型必须是void。
② 方法的名字由name指定,这个名字可以是除了那些在当前作用域中已经使用的标识符之外的任意合法标识符。
③ 参数列表是由类型、标识符对组成的序列,每对之间用逗号分开。参数实际上是方法被调用时接收传递过来的参数值的变量。如果方法没有参数,那么参数表就是空的。

5.2 方法的使用

实例:首先创建一个方法,方法完成乘法计算功能,然后在主函数中调用该方法。

public class methoddemo{
	int a = 12345679 , b = 81 ;
	public void times(int i,int j){
		System.out.println( i * j );
	}
	public static void main(String[] args){
		methoddemo m = new methoddemo();
		m.times(m.a,m.b);
	}
}

运行结果
999999999

5.3 构造方法

在Java程序里,构造方法所完成的主要工作是帮助新创建的对象赋初值。可将构造方法视为一种特殊的方法,它的定义方式与普通方法类似,其语法如下:

class 类名称{
	访问权限 类名称(类型1 参数1, 类型2 参数2, ... ...)
	
	{
		程序语句;
			构造方法没有返回值
	}
}

在使用构造方法的时候需注意以下两点。
(1)它具有与类名相同的名称。
(2)它没有返回值。

构造方法除了没有返回值,且名称必须与类的名称相同之外,它的调用时机也与一般的方法不同。一般的方法是需要时才调用,而构造方法是在创建对象时自动调用,并执行构造方法的内容。因此,构造方法无需在程序中直接调用,而是在对象产生时自动执行。

基于上述构造方法的特性,可利用它来对对象的数据成员做初始化的赋值。所谓初始化就是对象赋初值。

class Person{					// 声明了一个Person()的类
	public Person(){			// Person()类的构造方法,此方法
		System.out.println("public Person()");// 只含有一个输出语句
	}
}

public class TestConstruct{
	public static void main(String[] args){
		Person p = new Person();	//实例化了一个Person类的对象p,
			//此时会自动调用Person中无参构造方法,即在屏幕上打印信息
		//创建对象之后,就执行Person()这个方法了
	}
}

# 运行结果
public Person()

在类中声明的构造方法,会在实例化对象时自动调用。

在之前的程序中,在类中并没有声明任何构造方法,而程序不也一样可以正常运行吗?
- 实际上,读者执行javac编译java程序时,如果程序中没有明确声明一个构造方法的话,系统会自动为类加入一个无参的且什么都不做的构造方法,类似于下面代码。

public Person(){
}

所以,之前所使用的程序虽然没有明确地声明构造方法,也是可以正常运行的。

5.4 构造方法的重载

Java里,不仅普通方法可以重载,构造方法也可以重载。只是构造方法的参数个数不同,或是类型不同,便可定义多个名称相同的构造方法。

class Person{
	private String name;
	private int age;
	
	public Person (String n , int a){
	//已经声明了一个含有两个参数的构造方法。
	//Java程序中 只要明确地声明了构造方法,那么默认的构造方法就不会被自动生成。
	//只需要简单地修改以下Person类就可以了,可以在Person类中明确地声明一无参的且什么都不做的构造方法。
		name = n;
		age = a;
		System.out.println("public Person(String n,int a)");
	}
	
	public String talk(){
		return "我是"+name+",今年"+age+"岁";
	}
}

public class TestConstruct2{
	public static void main(String[] args){
		Person p = new Person();
		// 报错:找不到Person类的无参构造方法
		System.out.println(p.talk());
	}
}

运行结果:
在这里插入图片描述
案例2

class Person{
	private String name;
	private int age;
	
	public Person(){
	}		//在这里声明了一无参的且什么都不做的构造方法,
	 //此时再编译程序的话,就可以正常编译而不会出现错误了。
	
	public Person(String n,int a){
		name = n;
		age = a;
		System.out.println("public Person(String n,int a)");
	}
	
	public String talk(){
		return "我是:"+name+",今年:"+age+"岁";
	}
}

public class TestConstruct2{
	public static void main(String[] args){
		Person p = new Person();
		System.out.println(p.talk());
	}
}

运行结果
在这里插入图片描述

5.5 构造方法的私有

方法依实际需要,可分为public与private。构造方法也有public与private之分。到目前为止,所使用的构造方法均属于public,它可以在程序的任何地方被调用,所以新创建的对象也都可以自动调用它。如果构造方法被设为private,则无法在该构造方法所在类以外的地方被调用。

public class TestSingleDemo1{
	private TestSingleDemo1{	//在声明构造方法的时候,
		//这里声明为private类型,则此构造方法只能在本类内被调用。
		System.out.println("private TestSingleDemo1.");
	}

	public static void main(String[] args){
	//main方法也放在了TestSingleDemo1类的内部,
	//所以在本类中可以自己产生实例化对象
		new TestSingleDemo1();
	}
}


# 运行结果
private TestSingleDemo1.

一个类最终都会由外部去调用,构造方法虽然被私有了,但并不一定是说此类不能产生实例化对象,只是产生这个实例化对象的位置有所变化,即只能在本类中产生实例化对象。

class Person{

	String name;

	private static final Person p = new Person();
	//声明一个Person类的实例化对象,此对象是在Person类内部实例化,
	//所以可以调用私有构造方法。另外,此对象被标识为static类型,
	//表示为一个静态属性,同时此对象被私有化,
	//另外在声明Person对象时,加上了一个final关键字,
	//此关键字表示Person的对象p不能被重新实例化。

	private Person(){		//将Person类的构造方法封装起来,
							//外部无法通过其构造方法产生实例化对象。
		name = "张三";
	}

	public static Person getP(){
		return p;
	}
}

public class TestSingleDemo2{
	public static void main(String[] args){
		//声明一个Person类的对象
		Person p = null;  	//声明了一个Person类的对象p,
							//但未实例化。
		p = Person.getP();	//调用Person类中的getP()方法,
							//此方法返回Person()类的实例化对象。
		System.out.println(p.name);
	}	
}

# 运行结果
张三

5.6 在类内部调用方法

在一个Java程序中是可以通过对象去调用类中的方法的,当然类的内部也能互相调用各自的方法,比如在下面的程序中,修改了以前的程序代码,新增加了一个公有的say()方法,并用这个方法去调用私有的talk()方法。

class Person{
	private String name;
	private int age;
	
	private void talk(){
		System.out.println("我是:"+name+",今年:"+age+"岁");
	}
	
	public void say(){			//声明了一个公有方法say(),
						//此方法用于调用类内部的私有方法talk()。
		talk();
		//this.talk();
	}
	
	public void setName(String str){
		name = str;
	}
	
	public void setAge(int a){
		if(a>0){
			age = a;
		}
	}
	
	public String getName(){
		return name;
	}
	public int getAge(){
		return age;
	}
}

public class TestPersonDemo5{
	public static void main(String[] args){
		//声明并实例化一个Person对象p
		Person p = new Person();
		//给p中的属性赋值
		p.setName("张三");
		//在这里将p对象中的年龄属性赋值为30岁
		p.setAge(30);
		//调用Person类中的say()方法
		p.say();
	}
}

# 运行结果
我是:张三,今年:30

注意:
这个时候使用say()方法调用talk()方法。如果非要强调对象本身的话,也可以写成 this.talk() ; 的形式 。

6 练习

一、填空题

  1. 面向对象的程序设计有3个主要特征:封装性继承性多态性
  2. 在继承过程中,被继承的类称为父类,经继承产生的类称为子类
  3. 在Java中,多态的两种形式为方法重载成员覆写

二、简答题

简述Java中两种形式的多态

方法重载:在一个类中,允许多个方法使用同一个名字,但方法的参数不同,完成的功能也不同。
成员覆写:子类与父类允许具有相同的变量名称,数据类型不同,允许具有相同的方法名称,但完成的功能不同。

三、上机

定义一个包含name、age和like属性的Person类,实例化并给对象赋值,然后输出对象属性。

class Person{
	static String name;
	static int age;
	public static String like(){
		return "我叫"+name+",今年"+age+"岁";
	}
}

public class Test{
	public static void main(String[] args){
		Person p = new Person();
		p.name="KK";
		p.age=23;
		System.out.println(p.like());
	}
}

# 运行结果
我叫KK,今年23
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值