初学JAVA-8-对象和类、面向过程和面向对象

            其实本来准备这篇笔记先写数组,再通过Scanner引入简单的人机交互,之后再引出对象和类,面向过程和面向对象这个话题的。但是我思考了半天,还是决定先时候说对象和类、面向过程和面向对象这些事情。从我写第三篇笔记开始,我就一直感觉写的磕磕绊绊,从我们的第一个HelloWorld的例子开始,到上一个等差数列求和,所有的这些问题,我们都是在一个方法里完成的。是的,public static void main(String[] args),这个主方法,没有出过这个圈。

             我们都知道,JAVA是面向对象的语言,但是到现在为止,我们没有介绍过任何和面向对象有关的内容。全都是面向过程。忽然间我感觉,也许最开始我们就应该解释,什么是面向对象,什么是面向过程。我们最开始也使用了著名的HelloWorld作为第一个Java程序,但是这个程序最早是从C语言里面出来的。C语言是最著名的面向过程的语言。

              什么是面向过程?面对具体问题,从问题本身出发,关注问题解决的过程的编程思路,就是面向过程。比如我们之前举例的,对这个学生的成绩分析,然后写了一段代码。现在我们要分析这个学生的健康情况,我们再写一段代码,来解决这个问题。如果再分析这个学生的考勤情况呢,我们再写一段代码...我们关注的是一个个问题。

            什么是面向对象?关注事物本身,从事物本身出发,关注事物的属性和行为,就是面向对象的基本思想。比如上面所说的,我们从学生本身出发,学生的成绩,身体各项指标,考勤等都是这个学生的属性,上课、请假、体检、考试这些,甚至是逃课,都是这个学生的行为。我们从学生的层面来分析他的成绩,分析他的健康状况和考勤情况。

             也许你要问,那面向过程有什么区别?难道不还是要面对这些问题吗?不还是要写成绩分析的代码,健康情况分析的代码,考勤分析的代码吗?是的,编程最终还是要解决具体问题,但是和面向过程不同的是,我们的代码有了联系,成为了一个整体。当我们继续扩展,我们把学生的社会活动情况也纳入进来,面向过程只是多了一块代码,而面向对象却多了一块拼图。如果我们再扩展,把教师也添加进来,那从面向对象的角度,我们基本上已经可以构建一个学校了。而面向过程,只是多了另一堆代码。

             既然是面向对象,那总得有对象,那么什么是对象?什么是类?类我们已经知道了,我们之前的HelloWorld, MyFirstJavaClass, MySecondJavaClass,这都是类。然而就是这几个类,可能会让人更加迷惑,类的概念更加混乱。因为这些都是我们为了解决问题而创建的类,比如为了输出HelloWorld,为了计算1加到100,为了计算1+3+5+7...这是为了解决问题而创建的类,这是面向过程的思想。

                什么是类?类是一种区分,类是一种抽象,将一些具有相同属性和行为的对象提取出来,就成为了类。比如人类。也许人类这个词一瞬间拯救了你的大脑,你有一种豁然开朗的感觉,你正想努力理解类是什么,忽然看到人类这个词,你瞬间就明白了。也许我们对人类无法做最精确的定义,但是这个词瞬间把我们和动物、植物分开了。人类有什么属性?有身高、体重、性别、肤色等等等等,那人类有哪些行为?吃饭,睡觉,娱乐等等等等。有了人类,我们自然的知道还有其他的种类,比如哺乳类、爬行类、飞行类、植物里面有乔木类、灌木类等等。我们提取事物的共同特点,将他们归为一类。这个能力是面向对象的基本能力,我们称为抽象。

                与抽象对应的是具体,比如姚明打篮球,林丹打羽毛球,马龙打乒乓球,潘长江演小品,贾玲说相声这些都是很具体的对象,但是我们根据他们的特点,可以简单的将他们分为体育明星和文艺明星。我们也可以简单的将他们分为男明星和女明星。如果我们从职业特性来进行抽象,那我们现在可以分别定义这两个类了:SportStar 和 ArtStar。如果我们从性别角度来进行抽象,那我们可以定义另外两个类:MaleStar和FemaleStar。

                那么什么是对象?对象是类的实例,是类的具体表象。比如体育明星里,姚明是一个对象,马龙是一个对象,林丹是一个对象。文艺明星里,潘长江是一个对象,贾玲是一个对象。

                我们说过,面向对象关注事物的本身,关注事物的属性和行为,那么我们考虑一下体育明星有哪些属性和行为?比如姓名、性别、身高、从事的体育项目,这些是体育明星的属性;训练、休息、参赛、出席记者招待会等等,这些是他们的行为。在Java里,如何根据他们这些属性和行为定义这个类呢?

            

//声明一个名为SportStar的类,用来表示体育明星
public class SportStar{
	//声明体育明星的属性:姓名
	public String name;	
	//声明体育明星的属性:性别
	public String sex;
	//声明体育明星的属性:身高
	public double height;
	//声明体育明星的属性:年龄
	public int age;
	//声明体育明星的属性:从事体育项目
	public String sport;


	//声明体育明星行为:训练
	public String train(){
		String result = name+"变得更强了";
		return result;
	}


	//声明体育明星的行为:休息
	public void rest(){
		System.out.println(name+"休息了");
	}
	//声明体育明星的行为:参赛
	public void match(String sportname){
		System.out.println(name+"正在参加"+sportname);	
	}


	//声明体育明星的行为:出席记者招待会
	public String meeting(boolean flag){
		if(flag){
			return name+"参加了记者招待会";
		}else{
			return name+"拒绝参加记者招待会";
		}
	}


	//声明体育明星的行为:提供个人信息
	public String myInformation(){
		String information = "姓名:"+name+","+sex+","+age+"岁,身高"+height+"米,"+"从事"+sport+"运动";
		return information;
	}
}

上面我们定义了一个SportStar类,声明了他的各种属性和行为。我们可以看到,声明类的属性,就是在这个类里面声明变量。声明类的行为,就是定义一些方法。我们发现这个类没有main方法,那他怎么执行呢?我们现在要创建一个具体对象,要怎么操作呢?

        我们说过,main方法是程序的入口,我们最好不要在我们的类里提供main方法,我们专门提供一个类来为系统服务。

public class OfferServer{


	
	public static void main(String[] args){


		SportStar star = new SportStar();
		star.name = "姚明";
		star.sex = "男";
		star.height=2.26;
		star.age = 38;
		star.sport = "篮球";
		String info = star.myInformation();
		System.out.println(info);
		star.match("亚运会");


		SportStar star1 = new SportStar();
		star1.name = "林丹";
		star1.sex = "男";
		star1.height=1.78;
		star1.age = 35;
		star1.sport = "羽毛球";
		String info1 = star1.myInformation();
		System.out.println(info1);
		star1.match("世锦赛");
		String mess = star1.meeting(false);
		System.out.println(mess);
	}


}

            在java中我们使用new关键字来创建一个新的对象,在上面的程序中,我们使用了SportStar star和SportStar sta

r1分别声明了两个体育类明星,然后用他们指向两个新创建的SportStar对象,然后给这两个SportStar对象分别设置了姓名、年龄、身高、性别、参与的体育项目,并让他们提供了自身信息,以及分别让他们参加了亚洲杯和世锦赛,另外我们还让第二个对象拒绝参加新闻发布会...

        

           构造方法

            怎么创建一个新对象?我们知道是使用了new关键字和SportStar(),实际上每一个类都有其自己的构建方法,用于创建其,例如我们的OfferServer,我们也可以用一个new OfferServer()来创建一个新的OfferServer对象
public class OfferServer{

	
	public static void main(String[] args){
		OfferServer server = new OfferServer();
	}

}
               上面的代码中我们创建了一个OfferServer类的对象,那么创建一个对象的时候需要:
                1.声明:声明一个对象,包括对象的名称和类型
                2.实例化:使用new关键字来创建一个对象
                3.初始化:在这个对象被创建时,会调用这个构造方法初始化对象

                实际上,我们调用的就是这个构建方法,每个JAVA类都有一个默认的构建方法,这个方法是不带参数的,我们可以以显示的形式来重写这个构造方法。一个类可以有多个构造方法,但是构造方法的声明部分不能相同。


            构造方法的语法:
            public|protected|default|private 类名(参数1,参数2,参数3...){
                    初始化语句...
            }

            我们可以看到,与普通方法相比,构造方法是没有返回类型的,构造方法的名字必须和类名完全一致,构造方法可以没有参数,也可以有一个或者多个参数。还是以运动明星举例,我们现在为它添加几个构造方法。

            

//声明一个名为SportStar的类,用来表示体育明星
public class SportStar{
	//声明体育明星的属性:姓名
	public String name;	
	//声明体育明星的属性:性别
	public String sex;
	//声明体育明星的属性:身高
	public double height;
	//声明体育明星的属性:年龄
	public int age;
	//声明体育明星的属性:从事体育项目
	public String sport;
	//不带参数的构造方法
	public SportStar(){
		this.name = "马龙";
		this.sex = "男";
	}	
	//带一个String参数的构造方法
	public SportStar(String name){
		this.name = name;
	}
	//带两个参数的构造方法
	public SportStar(String name,String sex){
		this.name = name;
		this.sex = sex;
	}
	//带多个参数的构造方法
	public SportStar(String name,String sex,double height,int age,String sport){
		this.name = name;
		this.sex = sex;
		this.height = height;
		this.age = age;
		this.sport = sport;
	}
	//带更多参数的构造方法
	public SportStar(String name,String sex,double height,int age,String sport,String message){
		this.name = name;
		this.sex = sex;
		this.height = height;
		this.age = age;
		this.sport = sport;
		System.out.println(message);
	}	
	//声明体育明星行为:训练
	public String train(){
		String result = name+"变得更强了";
		return result;
	}

	//声明体育明星的行为:休息
	public void rest(){
		System.out.println(name+"休息了");
	}
	//声明体育明星的行为:参赛
	public void match(String sportname){
		System.out.println(name+"正在参加"+sportname);	
	}

	//声明体育明星的行为:出席记者招待会
	public String meeting(boolean flag){
		if(flag){
			return name+"参加了记者招待会";
		}else{
			return name+"拒绝参加记者招待会";
		}
	}

	//声明体育明星的行为:提供个人信息
	public void myInformation(){
		String information = "姓名:"+name+","+sex+","+age+"岁,身高"+height+"米,"+"从事"+sport+"运动";
		System.out.println(information);
	}
}

    在上面的例子中,我们一共定义了不带参数,带一个参数,带两个参数,带多个参数,带更多个参数的5个构造方法,现在我们来看看不同的构造方法的使用

public class OfferServer{

	
	public static void main(String[] args){
		//调用不带参数的构造方法
		SportStar star1 = new SportStar();
		star1.myInformation();
		//调用带一个参数的构造方法
		SportStar star2 = new SportStar("张继科");
		star2.myInformation();
		//调用带两个参数的构造方法
		SportStar star3 = new SportStar("梅西","男");
		star3.myInformation();
		//调用带多个参数的构造方法
		SportStar star4 = new SportStar("朱婷","女",1.98,24,"排球");
		star4.myInformation();
		//调用带更多参数的构造方法
		SportStar star5 = new SportStar("迈克尔乔丹","男",1.98,55,"篮球","全世界最伟大的篮球运动员");
		star5.myInformation();
	}

}

            我们在设计构造方法时,一般是根据这个类的主要属性来设计,因为我们是需要对具体对象的属性做初始化,所以虽然我们可以设置参数多于对象属性个数的构造方法,但是我们并不建议这样做,程序设计需要有实际意义。

             另外,我们说过创建对象时会初始化这个对象,也就是说这个对象的属性其实都已经设定值了,如果我们没有在初始化的时候为这些属性设定值,那么系统会默认为其设定值:整型类型变量属性默认为0,浮点型默认为0.0,布尔型默认为false,char类型默认为''(空字符文字),对象类型默认为null。

            在许多其他的文档资料中,对构造方法有许多不同的叫法,比如构建器、构造函数、构建方法、构建函数等等,我们只要知道这些都是指创建对象的方法就行了。

           null

                我们在上面的例子演示中看到了null,null是什么?null是一个非常非常特殊的值,它基本上是所有对象的默认初始化值。当表示当前引用的对象为空。在面试中我们经常会遇到的一个问题是String s = "";和String s = null;有什么区别?“”是一个长度为0的字符串对象,它是String类的实例,是真实存在的,而null表示当前的引用为空。我们只能用String类型的引用变量来 指向“”,而不能用其他类型的引用变量,比如我们不能用SportStar类型的引用变量来指向“”,SportStar star = ""是不正确的。但是SportStar star = null;是可以的,它表示我们声明了一个SportStar类型的引用变量,它指向空。

                请注意,除了少数的操作,任何对null的引用都会招来失败,比如SportStar star = null;star.myInformation();由于我们的引用变量star此时指向一个null,所以凭空调用它的myInformation方法是失败的,虚拟机毫不客气的送给你一个NullPointerException(空指针异常)。           

                null可以做哪些操作?

                除了我们上面说的初始化以外,还可以做==和!=判断,而且为了我们的代码安全,为了JVM不会动不动就给我们抛出NullPointerException,我们还经常会做这个操作,判断一个对象是不是空。

                

               this

            在上面的程序中,我们在构造方法里面使用了this关键字。通常,this可以用来调用属性和构造方法,当它用来调用属性时,this指本类对象自身。比如我们上面使用的this.name = name;
            当它用于调用构造方法时,this指本类类名。比如
public class OfferServer{
	
	public OfferServer(){
	}
	
	public OfferServer(String message){
		this();
		System.out.println(message);
	}
	
	public OfferServer(String message,boolean flag){
		this(message);
		if(flag){
			System.out.println("再输出一遍"+message);
		}
	}
	
	public static void main(String[] args){
		OfferServer of = new OfferServer("你好");
		of = new OfferServer("真的吗",true);
		of = new OfferServer("真的吗",false);
	}

}
        需要注意的是
        1.this调用构造方法时,必须是构造方法的第一句
        2.this调用的构造方法必须存在,也就是说,如果需要调用无参的构造方法,必须以显示的形式将无参的构造方法写出来
        

            属性的访问

            在上面的SportStar类中,我们定义了体育明星的几个属性,而我们使用了public这个修饰符。在之前讲到修饰符的时候我们已经知道,public是完全开放的,所有的外部使用者都可以访问这个属性。这意味着我们的属性完全的暴露在大众视野下。这不是一个好的操作,因为这意味着所有的人都可以修改这个属性。好的思路是我们降低属性的访问权限,提供专门的读取和修改属性的方法给外部用户。这个思路简单来说,就是暴露方法,而不暴露属性。具体的操作方法,是我们将属性变成私有的(使用private修饰符),然后提供公有的(public)修改属性和查询属性的方法。
//声明一个名为SportStar的类,用来表示体育明星
public class SportStar{
	//声明体育明星的属性:姓名
	private String name;	
	//声明体育明星的属性:性别
	private String sex;
	//声明体育明星的属性:身高
	private double height;
	//声明体育明星的属性:年龄
	private int age;
	//声明体育明星的属性:从事体育项目


	//提供设置姓名的方法
	public void setName(String name){
		this.name = name;
	}	
	//提供读取姓名的方法
	public String getName(){
		return this.name;
	}
	
	//提供设置性别的方法
	public void setSex(String sex){
		this.sex = sex;
	}
	//提供读取性别的方法
	public String getSex(){
		return this.sex;
	}
	
	//提供设置身高的方法
	public void setHeight(double height){
		this.height = height;
	} 
	//提供读取身高的方法
	public double getHeight(){
		return this.height;
	}
	
	//提供设置年龄的方法
	public void setAge(int age){
		this.age = age;
	} 
	//提供读取年龄的方法
	public int getAge(){
		return this.age;
	}

	//提供设置体育项目的方法
	public void setSport(String sport){
		this.sport = sport;
	}
	//提供读取体育项目的方法
	public String getSport(){
		return this.sport;
	}
	public String sport;
	//不带参数的构造方法
	public SportStar(){
		this.name = "马龙";
		this.sex = "男";
	}	
	//带一个String参数的构造方法
	public SportStar(String name){
		this.name = name;
	}
	//带两个参数的构造方法
	public SportStar(String name,String sex){
		this.name = name;
		this.sex = sex;
	}
	//带多个参数的构造方法
	public SportStar(String name,String sex,double height,int age,String sport){
		this.name = name;
		this.sex = sex;
		this.height = height;
		this.age = age;
		this.sport = sport;
	}
	//带更多参数的构造方法
	public SportStar(String name,String sex,double height,int age,String sport,String message){
		this.name = name;
		this.sex = sex;
		this.height = height;
		this.age = age;
		this.sport = sport;
		System.out.println(message);
	}	

	//声明体育明星行为:训练
	public String train(){
		String result = name+"变得更强了";
		return result;
	}

	//声明体育明星的行为:休息
	public void rest(){
		System.out.println(name+"休息了");
	}
	//声明体育明星的行为:参赛
	public void match(String sportname){
		System.out.println(name+"正在参加"+sportname);	
	}

	//声明体育明星的行为:出席记者招待会
	public String meeting(boolean flag){
		if(flag){
			return name+"参加了记者招待会";
		}else{
			return name+"拒绝参加记者招待会";
		}
	}
	public void myInformation(){
		String information = "姓名:"+name+","+sex+","+age+"岁,身高"+height+"米,"+"从事"+sport+"运动";
		System.out.println(information);
	}
}
            上面的代码中我们把全部的属性都替换成了private的,然后为每个属性设置了一个设置(setter)方法和一个读取方法(getter) 。有时候我们我们不希望我们的一些属性提供给外部设置,比如年龄。如果我们为我们的SportStar增加一个birthday的属性,那么我们其实可以根据生日来确定年龄。当生日被设置的时候,他的年龄也已经确定了。而且年龄只会随着时间的增加而增加,试想一下,我们设置了一个人的生日是2000年1月1日,然后设置他的年龄是80岁,是不是很可笑?除非你是在2080年1月1日看到这篇文章。
        暴露方法而不暴露属性,再往上,暴露接口而不暴露实体类,是一个重要的编程思想,我们称之为 封装。而上面的getter和setter方法,在真正的工作中,会每天用到。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值