黑马程序员————面向对象1(day5)

来源:互联网 发布:湖北卡五星麻将源码 编辑:程序博客网 时间:2024/06/05 14:37

----------------------ASP.Net+Android+IOS开发----------------------期待与您交流!

 

 

面向对象1

l  面向对象概述

l  类与对象的关系

l  成员变量和局部变量

l  匿名对象的应用

l  封装概述

l  构造函数

l  构造代码块

l  this关键字

面向对象的概述

 面向对象其实就是现实世界模型的自然延伸。可以将现实世界的任何实体都看做是对象,万物皆对象,对象之间通过消息相互作用。

       所有的面向对象编程语言都支持3个概念:封装,继承,多态。

       以后开发:其实就是找对象使用。没有对象,就创建一个对象。

       找对象,建立对象,使用对象,维护对象的关系。

对象

对象的特征分为静态特征和动态特征两种。静态特征指对象的外观、性质、属性等,动态特征指对象具有的功能、行为等。

人们将对象的静态特征抽象为属性,用数据来描述,在Java语言中称为变量;人们将对象的动态特征抽象为行为,用一组代码来表示,完成对数据的操作,在Java语言中称为方法。一个对象由一组属性和一组对属性进行操作的方法构成。

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

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

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

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

 

 

类和对象的关系

现实生活中的对象:张三,李四。

想要描述:提取对象中共性内容。对具体的抽象。

描述时:这些对象的共性有:姓名,性别,年龄,学习Java的功能

映射到Java中,描述就是class定义的类。

具体对象就是对应Java 在堆内存中用new建立实体。

类就是:对现实生活中事物的描述。

对象:就是对这类事物,实实在在存在的个体

 

 

对象的声明:            类名 对象名 = new 类名();

对象的使用:            对象名称.属性名

                                 对象名称.方法名()

需求:描述汽车(颜色,轮胎数)。描述事物其实就是在描述事物的属性和行为。

 

属性对应是类中的变量,行为对应的类中的函数(方法)。

其实定义类,就是在描述事物,就是在定义属性和行为。属性和行为共同成为类中的成员(成员变量和成员方法)。

代码如下:

package day05.MianXiangDuiXiang;class Car{//描述颜色String color = "红色";//描述轮胎数int num = 4;//运行行为void run(){System.out.println(color + ".." + num);}}public class CarDemo{public static void main(String[] args){//生产汽车。在java中通过new操作符来完成。//其实就是在堆内存产生一个实体。Car c = new Car();//c就是一个类类型变量。记住:类类型变量指向对象。//需求:将已有车的颜色改成蓝色。只会该对象做使用。在java指挥方式是:对象.对象成员c.color = "blue";c.run();Car c1 = new Car();c1.run();//red 4}}


 

成员变量和局部变量

作用范围:成员变量作用于整个类中。

          局部变量变量作用于函数中,或者语句中。

在内存中的位置:成员变量:在堆内存中,因为对象的存在,厂子在内存中存在。

                    局部变量:存在栈内存中。

 

匿名对象

匿名对象,顾名思义就是没有明确的声明的对象。可以简单地理解为只是用一次的对象,即没有任何一个具体的对象名称引用它。

匿名对象是对象的简化形式

匿名对象两种使用情况: 当对对象方法仅进行一次调用时

                              匿名对象可以作为实际参数进行传递

例:

class Person{String name = "张三";int age = 22;public String talk(){return "我是:" + name + ",今年:" + age + "岁";}}public class TestPerson{public static void main(String[] args){//声明了一个Person匿名对象,调用Person类中的talk()方法System.out.println(new Person().talk());}}


 

从程序中可以看到,用new Person()声明的对象并没有赋给任何一个Person类对象的引用,所以此对象只使用了一次,之后就会被Java的垃圾收集器回收。

匿名对象使用方式1:当对对象的方法只调用一次时,可以用匿名对象来完成,这样写比较简化。如果对一个对象进行多个成员调用,必须给这个对象起个名字。

匿名对象使用方式2:可以将匿名对象作为实际参数进行传递。

 

封装

封装:是指影藏对象的属性和实现细节,仅对外提供公共访问方式。

好处:将变化隔离

  便于使用

  提高重用性

  提高安全性

封装原则:将不需要对外提供的内容都影藏起来。把属性都影藏,提供公用方法对其访问。

封装属性:private属性类名 属性名;

封装方法:private 方法返回类型 方法名称(参数){}

例:

package day05.MianXiangDuiXiang;class Person{private String name;private int age;void talk(){System.out.println("我是: " + name + ", 今年: "+ age + "岁");}}public class TestPerson{public static void main(String[] args){//声明并实例化一个Person对象PPerson p = new Person();//给p中的属性赋值p.name = "张三";//将p对象中的年龄赋值为-22p.age = 22;//调用Person累中的talk()方法p.talk();}}


 

如果按上图程序运行的话,连编译都无法通过,所提示的错误为:属性(name、age)为私有的,所以不能由对象直接进行访问,则样就可以保证对象无法直接去访问类中的属性。

但如果非要给对象赋值的话,该怎么办?程序设计人员一般在类的设计时,会对属性增加一些方法,如setXxx()、getXxx()这样的共有方法来解决这一矛盾。

例:

class Person{private String name;private int age;void talk(){System.out.println("我是: " + name + ", 今年: "+ age + "岁");}public void setName(String str){name = str;}public String getName(){return name;}public void setAge(int a){if(a>0 && a<130)age = a;elseSystem.out.println("忽悠谁呢");}public int getAge(){return age;}}public class TestPerson{public static void main(String[] args){//声明并实例化一个Person对象PPerson p = new Person();//给p中的属性赋值p.setName("张三");//将p对象中的年龄赋值为-22p.setAge(22);//调用Person累中的talk()方法p.talk();}}


 

可以看出在本程序中,由于传入了一个-22的不合法年龄,这样在设置Person中属性的时候因为不满足条件而不能被设置成功,所以age的值依然为自己的默认值0。

之所以对外提供访问方式,就因为可以在访问方式中加入逻辑判断等语句。对访问的数据进行操作。提高代码健壮性。

注意:私有仅仅是封装的一种表现形式。用private声明的属性或方法只能在其类的内部被调用,而不能在类的外部被调用。

 

构造函数

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

class 类名称{

   访问权限 类名称(类型1 参数1,…){

       程序语句;

       …//构造方法没有返回值

}

}

特点:1.函数名与类名相同

      2.不用定义返回值类型

      3.不可以写return语句

作用:给对象进行初始化。

注意:1.默认构造函数的特点。

      2.多个构造函数是以重载形式存在的。

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

对象一建立就会调用与之对应的构造函数。

构造函数的作用:可以用于给对象进行初始化。

例:

class Person{//Person类的构造方法public Person(){System.out.println("public Person()");}}public class TestPerson{public static void main(String[] args){Person p = new Person();}}



 

从此程序中不难发现,在类中声明的构造方法看,会在实例化对象时自动调用。

问:在以前的程序中同样的方法来产生对象,类中也没有声明任何构造方法,程序不也一样可以正常运行吗?

实际上,在执行javac编译java程序的时候,如果在程序中没有明确声明一个构造方法的话,系统会自动为类加入一个无参的且什么都不做的构造方法,类似于下面代码:

   public Person(){   }


 

构造函数的小细节:

当一个类中没有定义构造函数时,那么系统会默认给该类加入一个空参数的构造函数。

当在类中定义了构造函数后,默认的构造函数就没有了。

 

什么时候定义构造函数呢?

当分析事物时,该事物存在具备一些特性或者行为,那么将这些内容定义在构造函数中。

小细节:

   {

      System.out.println("Person code run");

   }

问:以上代码是什么?它的作用?

答:构造代码块。作用:给对象进行初始化。

对象一建立就运行,而且优先于构造函数执行。

和构造函数的区别:

构造代码块是给所有对象进行统一初始化。

而构造函数是给对应的对象初始化。

构造代码块中定义的是不同对象共性的初始化内容。

例:

class Person{private String name;private int age;{cry();//这里就写入了构造代码块}Person(){System.out.println("A: 姓名 " + name + ", 年龄 " + age);}Person(String s){name = s;System.out.println("B: 姓名 " + name + ", 年龄 " + age);}Person(String s, int a){name = s;age = a;System.out.println("C: 姓名 " + name + ", 年龄 " + age);}public void cry(){System.out.println("Cry....");}}public class TestPerson{public static void main(String[] args){Person p = new Person();Person p1 = new Person("张三");Person p2 = new Person("李四",22);}}


 

其运行结果是:Cry....

A: 姓名 null,年龄 0

Cry....

B: 姓名张三,年龄 0

Cry....

C: 姓名李四,年龄 22

由以上程序可看出:对象一建立就运行,而且优先于构造函数执行。构造代码块是给所有对象进行统一初始化。

this关键字

this:看上去,是用于区分局部变量和成员变量同名情况。

this:就代表本类的对象抗到底代表哪一个呢?

     This代表它所在函数所属对象的引用。

     简单说:哪个对象在调用 this所在的函数,this就代表哪个对象。

例:

class Person{private String name;private int age;Person(String name){this.name = name;}Person(String name, int age){this.name = name;this.age = age;}public void speak(){System.out.println("姓名: " + name + " 年龄: " + age);}}public class TestPerson{public static void main(String[] args){Person p = new Person("张三");//这里就会把张三赋给了第7行的name,而这个name又把张三赋给了this.name也就是p.namePerson p1 = new Person("李四");//这里把李四赋给了第7行的name,而这个name又把张三赋给了this.name也就是p1.name p.speak();//这是p对象调用的speak方法,所以输出的是p里面的值,也就是张三  p1.speak();//这是p1对象调用的speak方法,所以输出的是p1里面的值,就是李四}}


 

this的应用:当定义类中功能时,该函数内部要用到调用该函数的对象时,这时用this来表示这个对象。但凡本类功能内部使用了本类对象,都用this表示。

例:

class Person{private String name;private int age;Person(int age){this.age = age;}public boolean compare(Person p){return this.age == p.age;}}public class TestPerson{public static void main(String[] args){Person p1 = new Person(20);Person p2 = new Person(22);//p1调用compare方法并把p2传入到compare方法里的对应的参数,所以第12行return this.age == p.age也可看作为p1.age == p2.ageboolean b = p1.compare(p2);System.out.println(b);//输出比较结果为假false}}


 

this关键字在构造函数间调用

this语句只能定义在构造函数的第一行,因为初始化要先执行。

例:

class Person{private String name;private int age;Person(String name){this.name = name;//这里被第12行调用并且把name的值赋给了p对象,做初始化}Person(String name, int age){//这里接收下面main函数传入的参数this(name);//调用第7行的构造方法并且把name里的值传入了第7行的namethis.age = age;}void talk(){System.out.println("姓名: " + name + " 年龄: " + age);}}public class TestPerson{public static void main(String[] args){Person p = new Person("张三", 22);p.talk();//输出p对象里的值}}


 

 

 

 

----------------------ASP.Net+Android+IOS开发----------------------期待与您交流!

详情请查看:http://edu.csdn.net

 

原创粉丝点击