先补上昨天的博文
面向对象程序设计
1 相关概念
何谓面向对象是什么意思呢?
面向对象程序设计是将人们认识世界过程中普遍采用的思维方法应用到程序设计中。
对象是现实世界中存在的事物,它们是有形的,也可以是无形的,对象的特征分为静态特征和动态特征两种。
静态的特征指对象的外观、性质、属性等;
动态的特征指对象具有的功能、行为等。
客观事物是错综复杂的,但人们总是从某一目的出发,运用抽象分析的能力,从众多的特征中抽取最具代表性、最能反映对象本质的若干特征加以详细研究。人们将对象的静态特征抽象为属性,用数据来描述,在 Java 语言中称之为变量;人们将对象的动态特征抽象为行为,用一组代码来表示,完成对数据的操作,在 Java语言中称之为方法,一个对象由一组属性和一组对属性进行操作的方法构成。
将具有相同属性及相同行为的一组对象称为类。在面向对象程序设计中,类是一个独的单位,它有一个类名,其内部包括成员变量,用于描述对象的属性;还包括类的成员方法,用于描述对象的行为。
在 Java 程序设计中,类被认为是一种抽象数据类型,这种数据类型,不但包括数据,还包括方法。
要利用类的方式来解决问题,必须用类创建一个实例化的类对象,然后通过类对象去访问类的成员变量,去调用类的成员方法来实现程序的功能。
一个类可创建多个类对象,它们具有相同的属性模式, 但可以具有不同的属性值。Java程序为每一个类对象都开辟了内存空间,以便保存各自的属性值。
类的特性
*封装性
封装是面向对象的方法所应遵循的一个重要原则。它有两个含义:一是指把对象的属性和行为看成一个密不可分的整体,将这两者“封装”在一个不可分割的独立单位(即对象)中。
封装机制的另一个特点是,为封装在一个整体内的变量及方法规定了不同级别的“可见性”或访问权限。
*继承性
拥有反映事物一般特性的类,然后在其基础上派生出反映特殊事物的类。在 Java 程序设计中,已有的类可以是 Java 开发环境所提供的一批最基本的程序——类库。用户开发的程序类是继承这些已有的类。被继承的类称为父类或超类,而经继承产生的类称为子类或派生类。
面向对象程序设计中的继承机制,大大增强了程序代码的可复用性,提高了软件的开发效率,降低了程序产生错误的可能性,也为程序的修改扩充提供了便利。
若一个子类只允许继承一个父类,称为单继承;若允许继承多个父类,称为多继承。目前许多面向对象程序设计语言不支持多继承。而 Java 语言通过接口(interface)的方式来弥补由于 Java 不支持多继承而带来的子类不能享用多个父类的成员的缺憾。
*多态性
多态是允许程序中出现重名现象;Java 语言中含有方法重载与成员覆盖两种形式的多态。
方法重载:在一个类中,允许多个方法使用同一个名字,但方法的参数不同,完成的功能也不同。
成员覆盖:子类与父类允许具有相同的变量名称,但数据类型不同,允许具有相同的方法名称,但完成的功能不同。
上述的材料中概念性东西太强,难以理解,多读几遍,然后在看看后面的程序,再回头来读几遍这个材料,就可以完全理解,这里不理解到后面的程序中各种概念我会通过实例给大家解释这些概念。(有很多起初我也不理解但看到后面的程序能理解80%希望你要努力呀!)
2 类与对象
从现在开始我们要进行程序的编写了,是面向对象的程序设计;类(class)和对象(object)就是面向对象方法的核心概念。类是对某一类事物的描述,是抽象的、概念上的定义;对象是实际存在的该类事物的个体,因而也称实例(Instance)。
同一个类按同种方法产生出来的多个对象,其开始的状态都是一样的,但是修改其中一个对象的时候,其他的对象是不会受到影响的。
类的声明
class 类名称
{
数据类型 属性;
方法名称(参数 1,参数 2…)
{
程序语句 ;定义方法的内容
return 表达式;
}
}
实例
class Person // 类名(类名标准写法大写开头)
{
String name; //定义变量
int age;
void talk() //创建方法
{
System.out.println("my name is :"+name+"my old is : "+age);
}
}
创建对象格式
类名 对象名= new 类名() ;
创建属于某类的对象,需要通过下面两个步骤来实现:
1、声明指向"由类所创建的对象"的变量
2、利用 new 创建新的对象,并指派给先前所创建的变量。
利用上面的类来创建一个对象
Person p ; // 先声明一个Person类的对象 p
p = new Person(); // 用 new关键字实例化Person的对象 p
也可以用下面的格式来写
Person p = newPerson() ; // 声明 Person 对象 p 并直接实例化此对象
注意:
对象只有在实例化之后才能被使用,而实例化对象的关键字就是new。
访问对象中某个变量或方法
访问属性:对象名称.属性名
访问方法:对象名称.方法名()
下面看一个实例来说明上边的东西
class Person //定义一个类
{
String name; //定义类中的变量
int age;
void talk() //创建类的方法
{
System.out.println("my name is :"+name+"my old is : "+age);
}
}
public classjava51
{
public static void main(String [] args)
{
Person p1 = new Person(); //用类实例化对象p1
Person p2 = new Person(); //用类实例化对象p1
p1.name ="robin"; //访问类中的变量并赋值
p1.age = 25;
p2.name ="lili"; //用类实例化多个对象
p2.age = 21;
p1.talk(); //访问类中的方法
p2.talk();
}
}
看到这里我相信各位都能对类和对象分清楚了吧,也大体了解类是干什么用的了;下面我们来看看类的第一个特性—封装性
封装性
先看一下实例
class Person
{
String name;
int age;
void talk()
{
System.out.println("my name is :"+name+"my old is : "+age);
}
}
public classjava51
{
public static void main(String [] args)
{
Person p1 = new Person();
Person p2 = new Person();
p1.name ="robin";
p1.age = -25;
p2.name ="lili";
p2.age = 21;
p1.talk();
p2.talk();
}
}
再看输出结果,肯定是robin的年龄是-25,显然这个程序设计有问题,为了避免这样的错误,我们要进行程序的封装(private)
再看实例:
class Person
{
private String name;
private int age;
void talk()
{
System.out.println("my name is :"+name+"my old is : "+age);
}
}
public classjava51
{
public static void main(String [] args)
{
Person p1 = new Person();
p1.name ="robin";
p1.age = -25;
p1.talk();
}
}
编译的时候报错
所提示的错误为:属性(name、age)为私有的,所以不能由对象直接进行访问。
程序设计人员一般在类的设计时,会对属性增加一些方法,如:setXxx()、getXxx()这样的公有方法来解决这一矛盾。
再看实例:
class Person
{
private String name; //封装了类的变量
private int age;
void talk()
{
System.out.println("my name is : "+name+"my old is :"+age);
}
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 java51
{
public static void main(String [] args)
{
Person p1 = new Person(); //用类实例化
p1.setName("robin"); //赋值
p1.setAge(-20);
p1.talk(); //调用方法
}
}
封装类中的属性或方法
封装属性:private 属性类型属性名
封装方法:private 方法返回类型方法名称(参数)
方法的封装
实例
class Person
{
private String name;
private int age;
private void talk() //封装方法
{
System.out.println("my name is : "+name+"my old is :"+age);
}
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 java51
{
public static void main(String [] args)
{
Person p1 = new Person();
p1.setName("robin");
p1.setAge(-20);
p1.talk();
}
}
编译报错:
可以发现 private 也是同样可以用来声明方法的,这样这个方法就只能在类的内部被访问了。如何解决这样的方法封装问题呢?
在类内部调用方法
在一个 java 程序中是可以通过对象去调用类中的方法的,当然类的内部也能互相调用各自的方法,比如下面的程序,在下面的程序中,修改了以前的程序代码,新增加了一个公有的 say()方法,并用这个方法去调用私有的 talk()方法。
实例:
class Person
{
private String name;
private int age;
private void talk()
{
System.out.println("my name is : "+name+"my old is :"+age);
}
public void say() //创建了一个公有的方法
{
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 java51
{
public static void main(String [] args)
{
Person p1 = new Person();
p1.setName("robin");
p1.setAge(28);
p1.say();
}
}
引用数据类型的传递
开始就已经提到过引用,java中使用引用来取代C++中的指针,那么什么是引用?
实例
class Person
{
String name;
intage;
}
public class java52
{
public static void main(String [] args)
{
Person p1 = null; // 声明一对象 p1,此对象的值为 null,表示未实例化
Person p2 = null; // 声明一对象 p2,此对象的值为 null,表示未实例
p1 = new Person(); // 实例化 p1 对象
p1.name = "liming";
p1.age = 25;
p2 = p1; // 将 p1 的引用赋给 p2
System.out.println("name :"+p2.name);
System.out.println("age :"+p2.age);
}
}
由程序中可以发现,在程序中并没有用 new 关键字为对象 p2 实例化,而到最后依然可以用 p2.name 与 p2.age 方式输出属性的内容,而且内容与p1 对象中的内容相似,也就是说在这道程序之中 p2 是通过 p1 对象实例化的,或者说 p1 将其自身的引用传递给了 p2。
注意:
如果在程序最后又加了一段代码,令p2=null,则之前由 p1 创建的实例化对象不再有任何对象使用它,则此对象称为垃圾对象。所谓垃圾对象,就是指程序中不再使用的对象引用,关于垃圾收集的概念,在本章的最后会有介绍。
实例:
class Change
{
intx ;
}
public class java53
{
public static void main(String [] args)
{
Change c = new Change();
c.x = 20;
fun(c);
System.out.println("x = "+c.x);
}
public static void fun(Change c1)
{
c1.x = 25;
}
}
这个实例有点绕,下面我对这个实例进行解释一下:
1、 声明一个类 Change 类中声明了一个变量x;
2、 在main中实例化了一个对象c,并给这个Change中的变量x赋值为20;
3、 调用了fun方法,在这个fun方法中调用了Change类,并实例化了c1,并给x赋值25;
4、 x的值从20变成了25。
匿名对象
没有明确实例化的对象,也可以简单的理解为只使用一次的对象,即没有任何一个具体的对象名称引用它。
class Info
{
private String name = "zhang san";
private int age = 25;
public String talk()
{
return "wo jiao : "+name+",jin nian : "+age+"sui";
}
}
public class java54
{
public static void main(String []args)
{
System.out.println(new Info().talk());
}
}
构造方法
构造方法的格式
class 类名称
{
访问权限 方法名称(类型 1 参数 1,类型 2 参数 2,…)
{
程序语句 ;
… // 构造方法没有返回值
}
}
注意:
1、 它具有与类名相同的名称
2、 它没有返回值
实例
class Gzao
{
public Gzao()
{
System.out.println("gou zao fang fa");
}
}
public class java55
{
public static void main(String [] args)
{
Gzao p = new Gzao();
}
}
在执行 javac 编译 java 程序的时候,如果在程序中没有明确声明一构造方法的话,系统会自动为类加入一个无参的且什么都不做的构造方法。类似于下面代码:
public Person()
{}
所以,之前所使用的程序虽然没有明确的声明构造方法,也是可以正常运行的。
构造方法的重载
在 Java 里,不仅普通方法可以重载,构造方法也可以重载。只要构造方法的参数个数不同,或是类型不同,便可定义多个名称相同的构造方法。
实例
class Person
{
private String name;
private int age;
public Person(String n,int a)
{
name = n;
age =a;
System.out.println("public Penson(String n,int a)");
}
public String talk()
{
return "wo shi : "+name+", jin nian : "+age;
}
}
public class java56
{
public static void main(String [] args)
{
Person p = new Person("robin",25); //第一次传递的参数是robin25
System.out.println(p.talk());
Person p2 = new Person("lili",20); //第二次传递的参数是 lili20
System.out.println(p2.talk());
}
}
下面咱们来看一个报错
实例内容
class Person
{
private String name;
private int age;
public Person(String n,int a)
{
name = n;
age =a;
System.out.println("public Penson(String n,int a)");
}
public String talk()
{
return "wo shi : "+name+", jin nian : "+age;
}
}
public class java56
{
public static void main(String [] args)
{
Person p = new Person();
System.out.println(p.talk());
}
}
上边的类的内容没有变化,这里的main中,没有给这p对象赋值,所以就出现了下面的报错
这个错误是说找不到无参Person构造方法,如果程序中没有声明构造方法,程序就会自动声明一个无参的且什么都不做的构造方法。在 java 程序中只要明确的声明了构造方法,则默认的构造方法将不会被自动生成。而要解决这一问题,只需要简单的修改一下 Person 类就可以了,可以在 Person类中明确地声明一无参的且什么都不做的构造方法。
上面的程序中的类中加一个无参构造方法就解决问题,大家试试吧!
public Person()
{}
本文出自 “运维时代” 博客,请务必保留此出处http://daomeng.blog.51cto.com/1655407/1826256
原文地址:http://daomeng.blog.51cto.com/1655407/1826256