1、什么叫面向对象?
面向对象(Object-Oriented)就是一种常见的程序结构设计方法
面向对象思想的基础是将相关的数据和方法放在一起,组合成一种新的复合数据类型,然后使用新创建的复合数据类型作为项目的基础。面向对象是一个很抽象的概念,它相对面向过程而言。
过程与对象都是一种解决问题的思想。
面向过程:强调的是功能行为,一种过程
面向对象:将功能封装到对象里,强调的是具备某功能的对象
按照面向对象的思想,可以把任何的东西看做对象.
实例了解---面向对象和面向过程的概念
例如,现在有两位师傅“面向过程”和“面向对象”要求设计一个首饰盒
1 面向过程师傅:用户提出哪些要求,师傅就针对用户的要求进行制作,直接制作出一个完整的整体,本身也不准备好做首饰盒需要的工作,而是需要什么再单独拿什么
2 面向对象师傅:针对用户提出的要求进行分析,并将分析的结果设计成一张完整的的图纸,与需求的用户确认,然后将一切的工作全部处理完之后再分块制作,最后将各个小的部分组装起来
面向对象的程序设计有封装性,继承性和多态性3个主要特点
封装性 :为封装在一个整体内的变量及方法规定不同级别的“可见性”或访问权限
继承:在java中,已有的类可以是java开发环境所提供的一批最基本的程序-类库,用户开发的程序累是继承这些已经有的。这样,现在类所描述过的属性及行为,和已定义的变量和方法,在继承产生的类中可以完全使用。根据继承机制,派生类继承超类的所有成员,并可以增加自己的一些成员。面向对象继承机制大大增强了程序代码的复用性,提高了软件开发效率
多态性;多态是面向对象程序设计的一个重要特征,。java语言中含有方法重载和对象多态2种形式。
方法重载:在一个类中,允许多个方法使用同一个名字,但方法的参数不同,完成的功能也不同
对象多态:子类对象可以与父类对象进行互相转换,而且根据其使用的子类不同,完成的功能也不同
类与对象
在面向对象中,类和对象时最基本,最重要的组成单元。类是抽象的,对象就是表示一个个具体的东西。
类的定义
类是由属性和方法组成。属性中定义类一个个的具体信息,实际上一个属性就是一个变量,而方法时一些操作的行为。
类的定义
class 类名称{
数据类型属性;
。。。
public 返回值得数据类型方法名称(参数1,参数2){
程序语句;
return 表达式;
}
}
代码实例--定义Person类
class Person{
//人中有姓名和年龄两个属性
String name ; //表示姓名
int age ; //表示年龄
public void tell(){
System. out.println("姓名:" + name + ";年龄:" + age ) ;
}
};
对象的创建和使用
要想使用一个类必须有对象的实例化才能使用。
对象创建格式
类名对象名称 = null//声明对象
对象名称 = new类名()//实例化对象
实例代码
class Person{
//人中有姓名和年龄两个属性
String name ; //表示姓名
int age ; //表示年龄
public void tell(){
System. out.println("姓名:" + name + ";年龄:" + age ) ;
}
};
public class Demo{
public static void main(String args[]){
Person per = new Person() ;//创建并实例化对象
}
};
PS:对象的实例化是要划分堆内存和栈内存的
所有的对象名称都在栈内存中,而对象的具体内容则保存在对应的堆内存中,必须是使用new关键字才能开辟堆内存空间。更准确的说,栈内存中实际上保存的是堆内存空间的访问地址
创建多个对象
同时创建多个对象,每个对象分别会占据自己的堆,栈空间。
实例代码
class Person{
String name ; //声明姓名属性
int age ; //声明年龄属性
public void tell(){ //取得信息
System. out.println("姓名:" + name + ",年龄:" + age ) ;
}
};
public class Demo{
public static void main(String args[]){
Personper1 = null ; //声明per1对象
Personper2 = null ; //声明per2对象
per1= new Person() ; //实例化per1对象
per2= new Person(); //实例化per2对象
per1. name = "张三" ; //设置per1中的name属性内容
per1. age = 30; //设置per1中的age属性内容
per2. name = "李四" ; //设置per2中的name属性内容
per2. age = 33; //设置per2中的age属性内容
System. out.print("per1对象中的内容 --> ") ;
per1.tell(); //调用类中的方法
System. out.print("per2对象中的内容 --> ") ;
per2.tell(); //调用类中的方法
}
};
结果:per1对象中的内容 -->姓名:张三,年龄:30
per2对象中的内容 -->姓名:李四,年龄:33
ps:类属于引用数据类型,就是指一段堆内存空间可以同时被多个栈内存指向。
对象的引用传递
class Person{
String name ; //声明姓名属性
int age ; //声明年龄属性
public void tell(){ //取得信息
System. out.println("姓名:" + name + ",年龄:" + age ) ;
}
};
public class Demo{
public static void main(String args[]){
Personper1 = null ; //声明per1对象
Personper2 = null ; //声明per2对象
per1= new Person(); //只实例化per1一个对象
per2= per1 ; //把per1的堆内存空间使用权给per2
per1. name = "张三" ; //设置per1中的name属性内容
per1. age = 30; //设置per1中的age属性内容
//设置per2对象的内容,实际上就是设置per1对象的内容
per2. age = 33; //设置per2中的age属性内容
System. out.print("per1对象中的内容 --> ") ;
per1. tell(); //调用类中的方法
System. out.print("per2对象中的内容 --> ") ;
per2. tell(); //调用类中的方法
}
};
结果:per1对象中的内容 -->姓名:张三,年龄:33
per2对象中的内容 -->姓名:张三,年龄:33
可以发现,2个对象的输出内容是一样的。实际上所谓的引用传递,就是将一个堆内存空间的使用权给多个栈内存空间,每个栈内存空间都可以修改堆内存的内容。
ps:一个栈空间只能指向一个堆内存空间,如果要想再指向其他的堆内存空间,必须先断开已有的指向
封装性
封装性是面向对象的第一大特性,所谓的封装性就是指堆外部不可见。在java中对于私有方法的属性,有明确的定义:只要是被封装的属性,则必须通过setter和getter方法设置和取得
封装格式:
属性封装:private属性方法属性名称
方法封装:private方法返回值方法名称(参数列表){}
实例代码
class Person{
private String name ; //声明姓名属性
private int age ; //声明年龄属性
public void setName(String n){ // 设置姓名
name = n ;
}
public void setAge(int a){ //设置年龄
if(a>=0&&a<=150){ //加入验证
age = a ;
}
}
public StringgetName(){ //取得姓名
return name ;
}
public int getAge(){ //取得年龄
return age ;
}
public void tell(){
System. out.println("姓名:" + name + ",年龄:" + age ) ;
}
};
public class Demo{
public static void main(String arsgh[]){
Personper = new Person() ; //声明并实例化对象
per.setName( "张三"); //调用setter设置姓名
per.setAge(10); //调用setter设置年龄
per.tell(); //输出信息
}
};
结果:姓名:张三,年龄:10
构造方法
在对象实例化时直接把对象的值赋给属性。
语句格式:
class 类名称{
访问权限类名称(类型1参数1,类型2 参数2){
程序语句;
}
}
PS:在构造方法的声明中一定要注意
构造方法的名称必须与类名称一致..
构造方法的声明处不能有任何返回值类型的声明..
不能再构造方法中使用return返回一个值..
实例代码---声明一个构造方法
class Person{
public Person(){ //声明构造方法
System. out.println("一个新的Person对象产生。" ) ;
}
};
public class Demo{
public static void main(String args[]){
System. out.println("声明对象:Person per = null ;") ;
Person per = null ; //声明对象时并不去调用构造方法
System. out.println("实例化对象:per = new Person() ;") ;
per= new Person() ;//实例化对象
}
};
结果:
声明对象:Person per = null ;
实例化对象:per = new Person() ;
一个新的Person对象产生。
PS:1在java中,如果一个类中没有明确的说明一个构造方法,则在编译时会直接生成一个无参数的,什么都不做的构造方法,也就是说,如果以上的person类中没有明确的声明构造方法,实际上编译之后的类就会为用户自动加上构造方法
2当调用new关键字实例化对象时,才会调用构造方法
通过构造方法为对象赋值
实例代码
class Person{
private String name ;
private int age ;
public Person(String n, int a){ //声明构造方法,为类中的属性初始化
this.setName(n) ;
this.setAge(a) ;
}
public void setName(String n){
name = n ;
}
public void setAge(int a){
if(a>0&&a<150){
age = a ;
}
}
public String getName(){
return name ;
}
public int getAge(){
return age ;
}
public void tell(){//获取类的信息
System. out.println("姓名:" + this.getName() + ";年龄:" + this.getAge()) ;
}
};
public class Demo{
public static void main(String args[]){
System. out.println("声明对象:Person per = null ;") ;
Personper = null ; //声明对象时并不去调用构造方法
System. out.println("实例化对象:per = new Person() ;") ;
per= new Person("张三" ,30) ;//实例化对象
per.tell();
}
};
结果:声明对象:Person per = null ;
实例化对象:per = new Person() ;
姓名:张三;年龄:30
匿名对象
匿名对象就是没有明确给出名字的对象。一般匿名对象值使用一次,而且你匿名对象只在对堆内存空间中开辟空间,而不存在栈内存的引用。
实例代码——匿名对象的使用
class Person{
private String name ;
private int age ;
public Person(String n, int a){ //声明构造方法,为类中的属性初始化
this.setName(n) ;
this.setAge(a) ;
}
public void setName(String n){
name = n ;
}
public void setAge(int a){
if(a>0&&a<150){
age = a ;
}
}
public String getName(){
return name ;
}
public int getAge(){
return age ;
}
public void tell(){
System. out.println("姓名:" + this.getName() + ";年龄:" + this.getAge()) ;
}
};
public class Demo{
public static void main(String args[]){
new Person("张三" ,30).tell() ;//这实际上就是一个匿明对象,与之前声明的不同,此处没有任何栈内存引用它,所以此对象使用一次后就等待被垃圾收集机回收
}
};
类设计分析实例-----Student类
定义并测试一个名称为Student的类,包括的属性有学号,姓名以及三门课程数学,英语和计算机的成绩,包括的方法有计算3门课程的总分,平均分,最高分和最低分
class Student{
private String stuno ;//声明学号属性
private String name ;//声明学生的名字属性
private float math ;//声明数学成绩
private float english ;//声明英语成绩
private float computer ;//声明计算机成绩
public Student(){}
public Student(String s,String n,float m,float e,float c){//构造方法,初始化各学科分数
this.setStuno(s) ;
this.setName(n) ;
this.setMath(m) ;
this.setEnglish(e) ;
this.setComputer(c) ;
}
//通过getter()和setter()方法对属性进行封装
public void setStuno(String s){
stuno = s ;
}
public void setName(String n){
name = n ;
}
public void setMath(float m){
math = m ;
}
public void setEnglish(float e){
english = e ;
}
public void setComputer(float c){
computer = c ;
}
public String getStuno(){
return stuno ;
}
public String getName(){
return name ;
}
public float getMath(){
return math ;
}
public float getEnglish(){
return english ;
}
public float getComputer(){
return computer ;
}
public float sum(){ //求和操作
return math + english + computer ;
}
public float avg(){ //求平均值
return this .sum() / 3 ;
}
public float max(){ //求最高成绩
float max = math ; //数学是最高成绩
max= max> computer?max: computer ;
max= max> english?max: english ;
return max ;
}
public float min(){ //求最低成绩
float min = math ; //数学是最高成绩
min= min< computer?min: computer ;
min= min< english?min: english ;
return min ;
}
};
public class Demo{
public static void main(String args[]){
Studentstu = null ; //声明对象
stu= new Student("hello-1" ,"world" ,95.0f,89.0f,96.0f) ;
System. out.println("学生编号:" + stu.getStuno()) ;
System. out.println("学生姓名:" + stu.getName()) ;
System. out.println("数学成绩:" + stu.getMath()) ;
System. out.println("英语成绩:" + stu.getEnglish()) ;
System. out.println("最高分:" + stu.max()) ;
System. out.println("最低分:" + stu.min()) ;
}
};
结果:学生编号:hello-1
学生姓名:world
数学成绩:95.0
英语成绩:89.0
最高分:96.0
最低分:89.0
this 关键字
this关键字的作用
1 表示类中的属性
2 可以使用this调用本类的构造方法
3 this表示当前对象
使用shis调用本类中的属性
代码实例
class Person{ //定义Person类
private String name ; //姓名
private int age ; //年龄
public Person(String name, int age){ //通过构造方法赋值
this.name = name ; // 明确表示为类中的name属性赋值
this.age = age ;//明确表示为类中的age属性赋值
}
public StringgetInfo(){ //取得信息的方法
return "姓名:" + name + ",年龄:" + age ;
}
};
public class Demo{
public static void main(String args[]){
Personper1 = new Person("张三" ,33) ; // 调用构造实例化对象
System. out.println(per1.getInfo()); //取得信息
}
};
结果:姓名:张三,年龄:33
PS:在类中访问属性是时,最好都加上this关键字
使用this调用构造方法
如果一个类中有多个构造方法,也可以利用this关键字互相调用
代码实例--使用this关键字调用本类的构造方法
class Person{ //定义Person类
private String name ; //姓名
private int age ; //年龄
public Person(){ //无参构造
System. out.println("新对象实例化" ) ;
}
public Person(String name){
System. out.println("新对象实例化" ) ;
this.name = name ;
}
public Person(String name, int age){ //通过构造方法赋值
this();
this.name = name ; // 明确为类中的name属性赋值
this.age = age ;// 明确为类中的age属性赋值
}
public StringgetInfo(){ //取得信息的方法
return "姓名:" + name + ",年龄:" + age ;
}
};
public class Demo{
public static void main(String args[]){
Personper1 = new Person("张三" ,33) ; // 调用构造实例化对象
System. out.println(per1.getInfo()); //取得信息
}
};
结果:新对象实例化
姓名:张三,年龄:33
PS:构造方法是在实例化对象时被自动调用的,也就是说在类中的所有方法中,只有构造方法时被优先调用的,所有使用this调用构造方法必须也只能放在构造方法的第一行。。
this调用构造犯法时一定要留一个构造方法作为出口,既程序中至少存在一个构造方法不使用this其他构造方法
this表示当前对象
this最重要的就是表示当前对象(当前正在调用的对象)
代码实例--对象的比较操作
class Person{ //定义Person类
private String name ; //姓名
private int age ; //年龄
public Person(String name, int age){
this.setName(name) ;
this.setAge(age) ;
}
public boolean compare(Person per){
//调用此方法时里面存在两个对象:当前对象、传入的对象
Personp1 = this ; //当前的对象,就表示per1
Personp2 = per ; //传递进来的对象,就表示per2
if(p1==p2){ //判断是不是同一个对象,用地址比较
return true ;
}
//之后分别判断每一个属性是否相等
if(p1.name .equals(p2.name)&&p1. age==p2. age){
return true ; //两个对象相等
} else{
return false ; //两个对象不相等
}
}
public void setName(String name){ // 设置姓名
this.name = name ;
}
public void setAge(int age){ //设置年龄
this.age = age ;
}
public String getName(){
return this .name ;
}
public int getAge(){
return this .age ;
}
};
public class Demo{
public static void main(String args[]){
Personper1 = new Person("张三" ,30) ; // 声明两个对象,内容完全相等
Personper2 = new Person("张三" ,30) ; // 声明两个对象,内容完全相等
//直接在主方法中依次取得各个属性进行比较
if(per1.compare(per2)){
System. out.println("两个对象相等!" ) ;
} else{
System. out.println("两个对象不相等!" ) ;
}
}
};
结果:两个对象相等!
PS:对象的比较是一个比较重要的概念。
小结
1 面向对象的三大特征为封装,继承,多态
2 类与对象的关系:类是对象的模板,对象时类的实例。类只能通过对象才可以使用
3 类属于引用数据类型,进行引用传递时,传递的是堆内存的使用权
4 类的封装性:通过private关键字进行修饰,被封装的属性不能被外部直接调用,而只能通过getter和setter完成。只要是属性,则必须全部封装
5 构造方法可以为类中的属性初始化,构造方法与类名称相同,无返回值类型的声明。若果在类中没有明确的定义粗话构造方法,则会自动生成一个无参数什么都不做的构造方法。在一个类中的构造方法可以重载,但是每一个类至少有一个构造方法
6 在java中使用this关键字可以表示当前的对象,通过"this.属性"可以调用本类中的属性,通过this.方法()可以调用本类中的其他方法,也可以通过this()的形式调用本类中的构造方法,但是调用时要要求放在构造方法的首行