java基础知识——13.类与对象
Posted L纸鸢
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java基础知识——13.类与对象相关的知识,希望对你有一定的参考价值。
这篇文章,我们来介绍java中的类与对象
目录
1.面向对象的介绍
下面,我们来对面向对象思想进行一下说明。
面向对象就是写程序的套路。面向:拿、找;对象:能干活的东西;面向对象编程:就是拿东西过来做对应的事情。
下面举例说明:
问:为什么用面向对象?
答:这与我们生活中的实际思维有关。在实际生活中中,当我们需要解决一个问题时,我们一般就会去找能解决这个问题的人或物,即找能解决问题的对象。所以使用面向对象编程可以使程序更简单更易理解
问:面向对象编程学些什么?
答: 学习获取已有的对象并使用;学习自己设计对象并使用
2.类的设计与使用
下面,我们来学习类与对象的设计和使用
2.1 类和对象
类(设计图):是对象共同特征的一种描述,是一种抽象
对象:是真实存在的具体东西
在java中,必须先设计类,再new出对象
2.1.1 如何定义类
下面,我们来学习一下如何定义类
定义类的基本格式如下:
public class 类名
//成员变量(代表属性,一般为名词)
//构造器(见下方)
//成员方法(代表行为,一般为动词)
//内部块(后面奖)
//内部类(后面讲)
实例如下:
创建对象的方法:
类名 对象名 = new 对象名()
实例如下:
使用对象的方法:
访问属性:对象名.成员变量
访问行为:对象名.方法名(...)
2.2 类的注意事项
javabean类:用来描述一类事物的类,里面不写main方法
测试类:编写main方法的类,我们可以在测试类中创建Javabean类的对象并进行赋值使用
注意事项:
- 类名首字母建议大写、英文、有意义,满足驼峰命名法,不能使用关键字,满足标志符规定
- 一个代码文件中可以定义多个类,但是只能有一个类是public修饰的,public修饰的类名必须是java代码的文件名
- 类的成员变量完整的定义格式为:修饰符 数据类型 变量名 = 初始化值;但是我们定义类的时候一般不赋值,系统会指定默认值
3.封装
面向对象的三大特征:封装,继承,多态
封装的原则:对象代表什么,就封装对应的数据,并提供数据对应的行为。
解释:
上面的话其实不太好理解。下面用具体实例的说明一下封装
例如:需求:人画圆,请对这个对象进行面向对象的设计。首先,我们肯定知道,画圆是一个方法。那么请问,画圆这个方法是放在人这个类中还是圆这个类中?答案是放在圆这个类中。这就是封装,下面提供两种解释。解释一:画圆需要知道圆的半径等相关数据,而这些数据在哪呢?在圆这个类中,所以就把这个方法放到圆这个类中。这也是上面所说的:对象代表什么,就封装对应的数据,并提供数据对应的行为。解释二:我们来分析一下这个题目,人画圆,涉及到两个事务:人和圆,我们按照封装的思想,一个类中只包含这个类的所有共同属性,也就是只包含这个类的东西,人这个类就包含人的东西,圆这个类就包含圆的东西,画圆,归根结底还是落在圆这件事务上,所有画圆就放到圆这个类中。说白了,封装,就是把相互纠缠的事物彻底分开,彼此打包组装起来,A是A,B是B,尘归尘,土归土,互不干扰;如有需要,进行调用,如何调用,后面会讲。
封装的好处:
- 让程序变的简单,干什么事,找什么对象,直接调用对象的方法
- java封装了需要方法类,便于我们的使用
3.1 private关键字
private:
- 是一个权限修饰符
- 可以修饰成员(成员变量和成员方法)
- 被其修饰的成员只能在本类中访问
如下图所示:
问:那怎么访问被private修饰的成员呢?
答:通过访问器与修改器
如下图所示:
set方法:给成员变量赋值,方法用public修饰
get方法:对外提供成员变量的值 ,方法用public修饰
这也是封装的一部分!!!
除了这个private关键字,还有public,default,protected
后面把这部分内容讲完了,会讲一下java这四大权限修饰符
4.this关键字
首先,我们来看一段代码:
如上图的第9行和第10行,第9行方法的参数中有关参数,名为brand,与我们类的成员变量重名了。那么就出现了问题,你在这个方法中调用brand变量,到底调用的是哪一个呢?不知道(实际上调用的是参数brand),当然,我们也可以不讲这个参数命名为brand,可以换个名字,但是我们java的命名规则为见名知意,所以也就只能命名为这个了。那么怎么办呢?
为了解决上述的问题,java引入了this关键字。
在讲this关键字之前,我们先讲一下成员变量与局部变量。
成员变量:定义在类中方法外的变量
局部变量:定义在方法中或方法内的变量
当成员变量与局部变量重名时,我们如果调用这个变量,有一个原则叫就近原则,意思是谁离调用出近就用谁。根据就近原则,我们可以知道,如果我们在上述代码的第十行中写brand,它调用的就是方法中的参数brand。为了调用我们的成员变量,this关键字就起作用了。
简单来说就是,在一个类中,this就代表这个类的对象,我们在this后面可以点出这个类的所有成员变量和成员方法,this相当于是测试类中的这个类的实例化对象。
this的本质:方法调用者的地址值
解释:我们知道,你创建一个类,你只是创建了一个模板,你并不能使用它,要使用它就必须初始化它,即创建它的对象。OK,你现在创建了它的对象了,这个对象有地址,你通过这个对象来调用这个类中的方法。假设,你调用的这个方法中有一个this关键字,此时,当代码执行到这条语句时,系统就会把你的对象的地址赋给this,然后this进行一系列的操作。就是这么简单。这就是this的本质,是方法调用者(即对象)的地址值。
5.构造方法
构造方法也叫构造器,构造函数
作用:在创建对象的时候给成员变量进行初始化的(创建时赋值的)
构造方法的格式:
修饰符 类名(参数)
方法体
特点:
- 方法名与类名相同,大小写也一致
- 没有返回值类型,连void都没有
- 没有具体的返回值(不能由return语句)
执行时机:
- 创建对象时由虚拟机调用,不能手动调用构造方法
- 每创建一次对象,就会调用一次构造方法
实例如下图所示:
第9——第17行,三个方法全为构造方法。
注意:当我们设计完类的时候,系统会默认给我设置无参的构造方法,当时,一旦我们手写了构造方法,那么原本的无参构造方法就会被覆盖
6.标准JavaBean
下面来说一下标准的javabean,前面说过一点,但是不具体,这里具体说一下;
标准Javabean的要求
- 类名要见名知意
- 成员变量使用private修饰
- 提供至少2个构造方法:无参构造方法,带全部参数的构造方法
- 成员方法:提供每个成员变量的访问器与修改器;如果还有其他的行为也应该写上
下面来看一下一个标准的javabean类:
public class User
private String name;
private int age;
private String IdNumber;
private String address;
public User()
public User(String name, int age, String idNumber, String address)
this.name = name;
this.age = age;
IdNumber = idNumber;
this.address = address;
public String getName()
return name;
public void setName(String name)
this.name = name;
public int getAge()
return age;
public void setAge(int age)
this.age = age;
public String getIdNumber()
return IdNumber;
public void setIdNumber(String idNumber)
IdNumber = idNumber;
public String getAddress()
return address;
public void setAddress(String address)
this.address = address;
7.对象内存图
下面,我们来介绍一下对象的内存图
内容回顾:
java的内存分配为:栈,堆,方法区,本地方法栈,寄存器
栈中存方法和方法中的内容,堆中存new出来的,方法区中放一个类的字节码文件(即当我们要用一个类的时候,这个类的字节码文件就会被加载到方法区中),本地方法栈和寄存器与硬件有关,不多赘述。
下面,我们根据代码来讲解一下吧
当我们在测试类中输入红框中的代码,并运行时,JVM至少要做以下7件事:
- 加载class文件(即等号左边的User)
- 申明局部空间变量 (即等号右边的LiSi)
- 在堆中开辟一块空间(即等号右边的new)
- 默认初始化(对堆中对象初始化)
- 显式初始化(对堆中对象初始化)
- 构造方法初始化
- 将堆中空间的地址赋值给等号左边的局部变量LiSi(即等号的作用)
下面,我们就对上面的代码进行一下内存分析:
这图画的很清楚了,大家可以参考这图来理解
8.成员变量与局部变量
成员变量:类中方法外的变量
局部变量:方法里面的变量
如下图所示:
成员变量与局部变量的区别:
java基础知识--抽象类与接口
抽象类与接口
1、Java 抽象类
1、引言:
在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,
这样的类就是抽象类。
抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。
由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用。也是因为这个原因,通常在设计阶段决定要不要设计抽象类。
2、在Java语言中使用abstract class来定义抽象类
1 /* 文件名 : Employee.java */
2 public abstract class Employee
3 {
4 private String name;
5 private String address;
6 private int number;
7 public Employee(String name, String address, int number)
8 {
9 System.out.println("Constructing an Employee");
10 this.name = name;
11 this.address = address;
12 this.number = number;
13 }
14 public double computePay()
15 {
16 System.out.println("Inside Employee computePay");
17 return 0.0;
18 }
19 public void mailCheck()
20 {
21 System.out.println("Mailing a check to " + this.name
22 + " " + this.address);
23 }
24 public String toString()
25 {
26 return name + " " + address + " " + number;
27 }
28 public String getName()
29 {
30 return name;
31 }
32 public String getAddress()
33 {
34 return address;
35 }
36 public void setAddress(String newAddress)
37 {
38 address = newAddress;
39 }
40 public int getNumber()
41 {
42 return number;
43 }
44 }
3、抽象方法
抽象方法是一种特殊的方法:它只有声明,而没有具体的实现。抽象方法的声明格式为:
abstract
void
fun();
抽象方法必须用abstract关键字进行修饰。如果一个类含有抽象方法,则称这个类为抽象类,抽象类必须在类前用abstract关键字修饰。因为抽象类中含有无具体实现的方法,
所以不能用抽象类创建对象。
4、在使用抽象类时需要注意几点:
1、抽象类不能被实例化,实例化的工作应该交由它的子类来完成,它只需要有一个引用即可。
2、抽象方法必须由子类来进行重写。
3、只要包含一个抽象方法的抽象类,该方法必须要定义成抽象类,不管是否还包含有其他方法。
4、抽象类中可以包含具体的方法,当然也可以不包含抽象方法。
5、子类中的抽象方法不能与父类的抽象方法同名。
6、abstract不能与final并列修饰同一个类。
7、abstract 不能与private、static、final或native并列修饰同一个方法。
5、抽象类和普通类的主要有三点区别
1)抽象方法必须为public或者protected(因为如果为private,则不能被子类继承,子类便无法实现该方法),缺省情况下默认为public。
2)抽象类不能用来创建对象;
3)如果一个类继承于一个抽象类,则子类必须实现父类的抽象方法。如果子类没有实现父类的抽象方法,则必须将子类也定义为为abstract类。
6、抽象类总结规定
1. 抽象类不能被实例化(初学者很容易犯的错),如果被实例化,就会报错,编译无法通过。只有抽象类的非抽象子类可以创建对象。
2. 抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
3. 抽象类中的抽象方法只是声明,不包含方法体,就是不给出方法的具体实现也就是方法的具体功能。
4. 构造方法,类方法(用static修饰的方法)不能声明为抽象方法。
5. 抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象类。
2、Java 接口
1、概念
接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。
接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法。
除非实现接口的类是抽象类,否则该类要定义接口中的所有方法。
接口无法被实例化,但是可以被实现。一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。另外,在 Java 中,接口类型可用来声明一个变量,他们可以成为一个空指针,或是被绑定在一个以此接口实现的对象。
接口特性
-
-
- 接口中每一个方法也是隐式抽象的,接口中的方法会被隐式的指定为 public abstract(只能是 public abstract,其他修饰符都会报错)。
- 接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量(并且只能是 public,用 private 修饰会报编译错误)。
- 接口中的方法是不能在接口中实现的,只能由实现接口的类来实现接口中的方法。
-
2、接口与类相似点
- 一个接口可以有多个方法。
- 接口文件保存在 .java 结尾的文件中,文件名使用接口名。
- 接口的字节码文件保存在 .class 结尾的文件中。
- 接口相应的字节码文件必须在与包名称相匹配的目录结构中。
3、接口与类的区别
- 接口不能用于实例化对象。
- 接口没有构造方法。
- 接口中所有的方法必须是抽象方法。
- 接口不能包含成员变量,除了 static 和 final 变量。
- 接口不是被类继承了,而是要被类实现。
- 接口支持多继承。
4、接口的声明
接口的声明语法格式如下
[可见度] interface 接口名称 [extends 其他的类名] {
// 声明变量
// 抽象方法
}
示例:
1 /* 文件名 : Animal.java */
2 interface Animal {
3 public void eat();
4 public void travel();
5 }
5、接口的实现
当类实现接口的时候,类要实现接口中所有的方法。否则,类必须声明为抽象的类。
类使用implements关键字实现接口。在类声明中,Implements关键字放在class声明后面。
可以使用这个公式:...implements 接口名称[, 其他接口, 其他接口..., ...] ...
示例:
1 /* 文件名 : MammalInt.java */
2 public class MammalInt implements Animal{
3
4 public void eat(){
5 System.out.println("Mammal eats");
6 }
7
8 public void travel(){
9 System.out.println("Mammal travels");
10 }
11
12 public int noOfLegs(){
13 return 0;
14 }
15
16 public static void main(String args[]){
17 MammalInt m = new MammalInt();
18 m.eat();
19 m.travel();
20 }
21 }
结果:Mammal eats Mammal travels
- 类在实现接口的方法时,不能抛出强制性异常,只能在接口中,或者继承接口的抽象类中抛出该强制性异常。
- 类在重写方法时要保持一致的方法名,并且应该保持相同或者相兼容的返回值类型。
- 如果实现接口的类是抽象类,那么就没必要实现该接口的方法。
在实现接口的时候,也要注意一些规则:
-
- 一个类可以同时实现多个接口。
- 一个类只能继承一个类,但是能实现多个接口。
- 一个接口能继承另一个接口,这和类之间的继承比较相似。
6、接口的继承
一个接口能继承另一个接口,和类之间的继承方式比较相似。接口的继承使用extends关键字,子接口继承父接口的方法。
1 // 文件名: Sports.java 2 public interface Sports 3 { 4 public void setHomeTeam(String name); 5 public void setVisitingTeam(String name); 6 } 7 8 // 文件名: Football.java 9 public interface Football extends Sports 10 { 11 public void homeTeamScored(int points); 12 public void visitingTeamScored(int points); 13 public void endOfQuarter(int quarter); 14 } 15 16 // 文件名: Hockey.java 17 public interface Hockey extends Sports 18 { 19 public void homeGoalScored(); 20 public void visitingGoalScored(); 21 public void endOfPeriod(int period); 22 public void overtimePeriod(int ot); 23 }
接口的多继承
在Java中,类的多继承是不合法,但接口允许多继承,。
在接口的多继承中extends关键字只需要使用一次,在其后跟着继承接口。
public interface Hockey extends Sports, Event
3、抽象类和接口的区别
1.语法层面上的区别
2)抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的;
3)接口中不能含有静态代码块以及静态方法,而抽象类可以有静态代码块和静态方法;
4)一个类只能继承一个抽象类,而一个类却可以实现多个接口。
2.设计层面上的区别
1)抽象类是对一种事物的抽象,即对类抽象,而接口是对行为的抽象。抽象类是对整个类整体进行抽象,包括属性、行为,但是接口却是对类局部(行为)进行抽象。
举个简单的例子,飞机和鸟是不同类的事物,但是它们都有一个共性,就是都会飞。那么在设计的时候,可以将飞机设计为一个类Airplane,将鸟设计为一个类Bird,但是不能将 飞行
这个特性也设计为类,因此它只是一个行为特性,并不是对一类事物的抽象描述。此时可以将 飞行 设计为一个接口Fly,包含方法fly( ),然后Airplane和Bird分别根据自己的需要实现Fly
这个接口。然后至于有不同种类的飞机,比如战斗机、民用飞机等直接继承Airplane即可,对于鸟也是类似的,不同种类的鸟直接继承Bird类即可。从这里可以看出,继承是一个 "是不
是"的关系,而 接口 实现则是 "有没有"的关系。如果一个类继承了某个抽象类,则子类必定是抽象类的种类,而接口实现则是有没有、具备不具备的关系,比如鸟是否能飞(或者是否
具备飞行这个特点),能飞行则可以实现这个接口,不能飞行就不实现这个接口。
2)设计层面不同,抽象类作为很多子类的父类,它是一种模板式设计。而接口是一种行为规范,它是一种辐射式设计。
什么是模板式设计?
最简单例子,大家都用过ppt里面的模板,如果用模板A设计了ppt B和ppt C,ppt B和ppt C公共的部分就是模板A了,如果它们的公共部分需要改动,则只需要改动模板A就可以了,不需
要重新对ppt B和ppt C进行改动。而辐射式设计,比如某个电梯都装了某种报警器,一旦要更新报警器,就必须全部更新。也就是说对于抽象类,如果需要添加新的方法,可以直接在抽
象类中添加具体的实现,子类可以不进行变更;而对于接口则不行,如果接口进行了变更,则所有实现这个接口的类都必须进行相应的改动。
参考博客:
http://www.cnblogs.com/dolphin0520/p/3811437.html
http://www.runoob.com/java/java-interfaces.html
http://blog.csdn.net/chenssy/article/details/12858267
以上是关于java基础知识——13.类与对象的主要内容,如果未能解决你的问题,请参考以下文章