面向对象(Object-Oriented,简称OO)就是一种常见的程序结构设计方法。
面向对象思想的基础是将相关的数据和方法放在一起,组合成一种新的复合数据类型,然后使用新创建的复合数据类型作为项目的基础。
Java语言是纯粹的面向对象的程序设计语言,这主要表现为Java完全支持面向对象的三种基本特征:继承、封装和多态。Java语言完全以对象为中心,Java程序的最小程序单位是类,整个Java程序由一个一个的类组成。
Java完全支持使用对象、类、继承、封装、消息等基本概念来进行程序设计,允许从现实世界中客观存在的事物(即对象)出发来构造软件系统,在系统构造中尽可能运用人类的自然思维方式。
面向对象是相对于面向过程而言的,面向过程强调的是功能行为,是具体的执行者。而面向对象强调的是具备了功能的对象,由面向过程的执行者变成了指挥者,调用对象的功能,指挥者对象做事情。他是一种符合人们思考问题的一种习惯的思想,能够将复杂的问题简单化。
面向对象有三个特征:封装(encapsulation)、继承(inheritance)、多态(polymorphism)
开发其实就是找对象使用,没有对象,就自己创建一个对象。
找对象、建立对象、使用对象、维护对象的关系。
/*
* 类和对象的关系。
*
* 现实生活中的对象:张三、李四。
* 想要描述:提取对象中的共性内容,对具体的抽象。
* 描述时:这些对象的共性有:姓名、性别、年龄、学习java的功能。
*
* 映射到java中,描述就是class定义的类
* 具体对象就是对应java在堆内存中用new建立的实体。
*
* 类就是:对现实生活中事物的描述。
* 对象:就是这类事物,实实在在存在的个体。
*/
l 可以理解为:
• 类就是图纸
• 汽车就是堆内存中的对象
类的定义:
类是一组事物共有特征和功能的描述。类是对于一组事物的总体描述,是按照面向对象技术进行设计时最小的单位,也是组成项目的最基本的模块。类的概念是抽象的,类似于建筑设计中的图纸,是对于现实需要代表的具体内容的抽象。类只包含框架结构,而不包含具体的数据。所以类代表的是总体,而不代表某个特定的个体。
在类中定义其实都称之为成员。成员有两种:
1:成员变量:其实对应的就是事物的属性。
2:成员函数:其实对应的就是事物的行为。
所以,其实定义类,就是在定义成员变量和成员函数。但是在定义前,必须先要对事物进行属性和行为的分析,才可以用代码来体现。
定义类:
语法格式:
[< 修饰符>] class < 类名>
{
[<属性声明>]
[<构造器声明>]
[<方法声明>]
}
说明:修饰符public:类可以被任意访问
类的正文要用{ }括起来
定义属性:
语法格式:
[<修饰符>] 类型 < 属性名> [=初值] ;
说明:修饰符 private: 该属性只能由该类的方法访问。
修饰符 public: 该属性可以被该类以外的方法访问。
类型:任何基本类型,如int、boolean或任何类。
定义方法:
语法格式:
<修饰符> <返回类型> <方法名>([< 参数表>]) {
[< 语句>]
}
说明: 修饰符:public,private,protected等。
返回类型:return语句传递返回值。没有返回值:void。
对象的创建和引用:
使用 new +构造方法 创建一个新的对象;
使用 “对象名.对象成员” 的方式访问对象成员(包括属性和方法);
//描述汽车.描述事物其实就是在描述事物的属性和行为。
//属性对应类中的变量,行为对应类中的函数(方法)。
//其实定义类,就是在描述事物,定义事物的属性和行为。属性和行为共同成为类中的成员(成员变量和成员方法(函数))。
/*
* 成员变量和局部变量:
成员变量作用于整个类中。
局部变量作用于函数中,或者语句中。
在内存中的位置:
成员变量:在堆内存中,因为对象的存在才在内存中存在。
局部变量:存在于栈内存中。
*/
比如说,我们描述一个汽车类。汽车是一类事物,它有很多属性,其中包括颜色属性、轮胎个数属性,还有运行的run的方法,我们可以通过面向对象的思想把它描述成一个类。代码如下:
定义一个汽车类:
class Car
{
//描述颜色
String color = "红色";
//描述轮胎数
int num = 4;
//运行行为
void run()
{
System.out.println(color+"..."+num);
}
public static void main(String[] args)
{
Car c = new Car();
c.num = 8;
c.run();
}
}
实例化一个汽车对象和指挥对象做事情的具体过程:
public classCarDemo
{
public static void main(String[] args)
{
//生产汽车,在java中通过new操作符来完成。
//其实就是在堆内存中产生一个实体。
Car c = new Car();//c就是一个类类型变量。记住:类类型变量指向对象。
//需求:将已有车的颜色改成蓝色,指挥对象做事情。在java中的指挥方式是: 对象.对象成员
c.color = "blue";
c.run();//blue 4轮胎
Car c1 = new Car();
c1.run();//红色4轮胎
//匿名对象使用方法之一:当对对象的方法只调用一次时,可以用匿名对象完成,这样写比较简化。
//如果对一个对象进行多个成员进行调用,必须给这个对象起个名字。
//匿名对象的使用方式二:可以用匿名对象作为实际参数进行传递。
new Car().num = 9;
new Car().color = "blue";
new Car().run();
Car q = new Car();
Show(q);
}
//需求:汽车修配厂。对汽车进行改装,将来的车改成黑色3个轮胎。
public static void Show(Car c)
{
c.num = 3;
c.color = "black";
c.run();
}
}
封装:
是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。
封装的好处:
• 将变化隔离。
• 便于使用。
• 提高重用性。
提高安全性
封装的原则:
将不需要对外提供的内容都隐藏起来。
• 把属性都隐藏,提供公共方法对其访问。
private关键字:
• 是一个权限修饰符。
• 用于修饰成员(成员变量和成员函数)
• 被私有化的成员只在本类中有效。
常用之一:
• 将成员变量私有化,对外提供对应的set ,get方法对其进行访问。提高对数据访问的安全性。
•
Java中通过将数据声明为私有的(private),再提供公开的(public)方法:getXXX和setXXX实现对该属性的操作,以实现下述目的:
– 隐藏一个类的实现细节;
– 使用者只能通过事先定制好的方法来访问数据,可以方便地加入控制逻辑,限制对属性的不合理操作;
– 便于修改,增强代码的可维护性;
代码示例:
public classPerson {
//定义一个私有化的成员属性name
private String name;
//定义一个私有化的成员属性age
private int age;
//构造函数
public Person() {
this.name = name;
this.age = age;
}
//提供公有的访问属性name的方法
//getName方法,返回属性name
public String getName() {
return name;
}
//setName方法,设置属性name的值
public void setName(String name) {
this.name = name;
}
//提供公有的访问属性age的方法
//getAge方法,返回属性值age
public int getAge() {
return age;
}
//setAge方法,设置属性age的值
public void setAge(int age) {
this.age = age;
}
}
构造方法:
• 构造方法的特征
– 它具有与类相同的名称;
– 它不含返回值;
– 注意:在构造方法里不含返回值的概念是不同于“void”的,在定义构造方法时加了“void”,结果这个方法就不再被自动调了。
– 不可以写return语句
构造方法的作用:当一个类的实例对象刚产生时,这个类的构造方法就会被自动调用,我们可以在这个方法中加入要完成初始化工作的代码。
注意:
构造方法的定义:
语法格式:
< 修饰符> <类名>([< 参数表>]) {
[< 语句>]
}
默认的构造函数特点:
– 默认构造方法没有参数
– 默认构造方法没有方法体
– 默认的构造方法:Person(){}
所以:不编写构造方法就能用new Xxx()创建类的实例。
This关键字:
this:代表对象。就是所在函数所属对象的引用。
this到底代表什么呢?哪个对象调用了this所在的函数,this就代表哪个对象,就是哪个对象的引用。
开发时,什么时候使用this呢?
在定义功能时,如果该功能内部使用到了调用该功能的对象,这时就用this来表示这个对象。
this 还可以用于构造函数间的调用。
调用格式:this(实际参数);
this对象后面跟上 . 调用的是成员属性和成员方法(一般方法);
this对象后面跟上 () 调用的是本类中的对应参数的构造函数。
注意:用this调用构造函数,必须定义在构造函数的第一行。因为构造函数是用于初始化的,所以初始化动作一定要执行。否则编译失败。
static(静态)关键字:
/*
* 静态:static
* 用法:是一个修饰符,用于修饰成员(成员变量和成员函数)
* 当成员被静态修饰后,就对了一种调用方式,除了可以被对象调用外,还可以直接被类名调用。写法格式:类名.静态成员
*
* static特点:
* 1.随着类的加载而加载。
* 也就是说,静态会随着类的消失而消失。说明他的生命周期最长。
* 2.优先于对象而存在。
* 明确一点:静态是先存在,对象是后存在的。
* 3.被所有的对象所共享。
* 4.可以直接被类名所调用。
*
* 实例变量和类变量的区别:
* 1.存放位置。
* 类变量随着类的加载存在于方法区中。
* 实例变量随着对象的建立而存在于堆内存中。
* 2.生命周期。
* 类变量的生命周期最长,随着类的消失而消失。
* 实例变量生命周期随着对象的消失而消失。
*
* 静态的使用注意事项:
* 1.静态方法只能访问静态成员。
* 非静态方法既可以访问静态也可以访问非静态。
* 2.静态方法中不可以定义this,super关键字。
* 因为静态优先于对象存在,所以静态方法中不可以出现this。
* 3.主函数就是静态的。
*
* 静态有利有弊。
* 利:对对象的共享数据进行单独空间的存储,节省空间。没有必要每一个对象中都存储一份。
* 可以直接被类名调用。
* 弊端:生命周期过长。
* 访问出现局限性。(静态虽好,只能访问静态。)
*/
class Person
{
static String name;//成员变量,实例变量。
static String country = "CN";//静态的成员变量,类变量。
public static void show()
{
System.out.println("name="+name+"::country="+country);
}
}
classStaticDemo
{
public static void main(String[] args)
{
//Person p = new Person();
//p.name = "张三";
//p.show();
//System.out.println(p.country);
//System.out.println(Person.country);
Person.show();//调用静态方法,只需通过类名.方法名即可。
}
}
* 什么时候使用静态?
* 要从两方面下手:
* 因为静态修饰的内容有成员变量和成员函数。
*
* 什么时候定义静态(类变量)变量呢?
* 当对象中出现共享数据的时,该数据被静态所修饰。
* 对象中的特有数据要定义成非静态存在于堆内存中。
*
* 什么时候定义静态函数呢?
* 当功能内部没有访问到非静态数据(对象的特有数据)
* 那么该功能可以定义成静态的。
*/