面向对象
什么是面向过程编程?
面向过程编程:我个人理解为这其实就是一个过程化的编程。注重的是执行的过程
什么是面向对象?
面向对象是一种思想,只是从执行过程转变成指挥(调用)的过程。将功能封装进对象,强调具备了功能的对象,面向对象是基于面向过程的。为什么说是基于对象呢?其实简单的来说:就是将一些功能执行的过程封装在一个对象里面。然后我们需要使用这个功能的时候只需要调用他的这个对象就可以了。比如说我们将学生读书的这个过程封装在读书这个对象中。当我们需要调用读书这个过程的时候我们就只需要调用读书这个方法了。这里就充分的体现了封装的好处。只要把一些功能封装在了某个对象中,不但自己可以随时调用它里面的任何功能,别人也可以调用。所以说面向对象在现实生活中随处可见,其实我们生活中使用的每一个东西我们都可以把他看做一个对象。将使用他的过程做为一个封装到这个对象里面我们使用他就调用就是了。所以嘛一切都是对象。使用的过程就可以定义成方法。
比如说: 关灯 开灯 这样的就是一个过程 而开灯 关灯强调的是 灯这个对象 而灯有很多的功能
所以说我们只要定义一个灯的对象。调用他的时候就可以方便的使用他的功能。
而开门和关门也是一个过程 他们强调的都是门这个对象 而门有很多的功能,所以我们就将门这个对象封装起来
需要使用门的功能的时候我们就只需要调用这个对象就可以了
面向对象的三大特性:
封装(encapsulation) 继承(lnheritance) 多态(polymorphism)
类与对象:
类(class)和对象(object)就是面向对象方法的核心概念
类是对某一类事物的描述是抽象的,概念上的定义;
对象是实际存在的该类事物的个体因而且也称实例(instance)
比如:汽车的设计图 这个是抽象的 而对象就是按图纸生产出来的汽车
一个图纸是可以对应多个对象的 也可以说:一个类按同种方法产生出来多个对象
类的定义:
类可以将数据与函数一起封装在一起。这里的数据表示类的属性。函数(方法)从名字就可以看到这个是类的行为。定义类就是要定义行为和属性。
class person//这里定义了一个叫人的类
{
int age;//这里就定义了一个属性 类的属性也叫成员变量
void shout()//定义了一个方法 ,类的方法也叫成员函数
{
System.out.print("my age is"+age);//一个类的方法可以直接访问类中的任何成员(包括成员变量和成员函数)就好比这里shout方法直接访问同一个类中的age方法
}
}
注意:一个方法中如果有成员变量和局部变量,该方法中对这个变量名的访问是局部变量而不再是成员变量
也就是同名的变量局部变量优先成员变量访问。
局部变量也就是在方法的内部再重新定义一个变量如下
class person1
{
int age;
void shout()
{
int age=18;//这里重新定义了一个变量 这个变量就是局部变量
System.out.println("my age is"+age);
}
}//这里使用shout的打印方法调用的就不再上成员变量了而且是与之同名的局部变量。
对象的产生与使用:
要想实现类的属性和方法必须的创建对象。就好比上面的汽车只有了这个图纸是没有办法去实现他的功能的。所以我们要生产汽车。生产汽车也就好比创建对象
要创建对象必须要使用new关键字和想要创建对象的类的名字就好比上面代码的person这就是类名
如: person p=new person();
以类名做为变量类型定义了一个变量P来指向右边通过new关键字创建一个person类的实例对象
p这个变量就是对象 的引用句柄对象的引用
句柄就是在栈中分配一个变量对象
注意:在new语句的类名后一定要跟着();
不会画画得很差呵呵 这就是一创建对象的过程
变量在初始化之前是不能使用的 除了基本数据类型之外的变量类型都 是引用类型比如 说创建对象是用到的person这个类型
这是成员变量的一些初始值
创建好了新的对象之后我们就可以使用 “ 对象名.对象成员 ” 来访问对象的成员
比如:
class persondemo
{
public static void main(String[ ] args)
{
person p=new person();
person p1=new person();
p.age=18;//这里改变了p这个对象 的age属性,但不会影响到p1这个对象 的age属性
p.shout();//当调用这个对象 的方法时该方法内部所访问的成员变量是这个对象 自身的成员变量
p1.shout();//这里没有对p1这个对象的age的属性进行改变那么会打印他的初始值
}
}
每个创建的对象 都 有自己的生命周期,对象只能在其有效的生命周期内被使用,当没有引用变量指向这个对象 里那么这个对象 就会变成 垃圾汉有再被使用如
{
person p=new person();
....
}这是因为离开这的作用域失败,person对象成为垃圾
或者
{
person p=new person();
p=null;
}//这里因为在执行完p=null后被赋值为空不能指向任何对象所以这个对象不再被任何句柄所引用变成了垃圾
{
person p=new person();
person p1=p;
p=null
....
}这里执行完p=null后不会变成 垃圾还会被p1所引用直到p1走出其作用域而无效才会变成垃圾
对象的比较
有两种方式可以用于对象之间的比较“ == ”运算符 和 “equals()方法”“==”是比较两个变量值是否相等,equals方法用于比较两个对象的内容是否一致
简单的说就是一个比较变量的值一个比较内容
如
class comparedemo { public static void main(String[] args) { String str1= new String("abc"); String str2= new String("abc"); String str3=str1; if(str1==str2) System.out.println("str1==str2"); else System.out.println("str1!=str2"); if(str1==str3) System.out.println("str1==str3"); else System.out.println("str1!=str3"); } }
这里会出现str1=str3但是str1!=str2
因为str1是赋值给str3的所以无论是什么str1都=str3除了名不同哈
但是str1!=str2是因为我们仅仅知道了他们的内容不同不知道他们的地址值什么的
在这里如果用equals方法的话那么就会出同str1=str2=str3
class comparedmeo { public static void main (String[] args) { String str1=new String("abc"); String str2=new String("abc"); String str3=str1; if(str1.equals(str2)) System.out.println("str1==str2") else System.out.println("str1!=str2"); if(str1.equals(str3)) System.out.println("str1==str3"); else System.out.println("str1!=str3"); } }
这里是比较两个内容是否相等为了方便点后面字符串还是用的数据类型比较符弄的
打印结果 str1==str2 str1 ==str3
小知识点:
怎么样比较两个数组的内容是否相等呢?
==是用来比较数据类型的 但是equals()方法是用来比较两个对象内容是否相同的所以我们可以用一下equals()方法来比较呢毕竟都是用new实例化后的
匿名对象:
创建完对象,在调用对象 的方法时不定义对象的句柄,而是直接调用这个对象的方法这样的对象叫匿名对象。
格式:new person().shout();这个对象没有句柄而是直接用new这个字创建的person类的对象并直接调用它的shout()
方法结果和先那样的对象方法结果一样区别就是这个执行完了过后会变成垃圾、
使用匿名对象的两种情况:
1.如果对一个对象只需要进行一次方法调用,那么就可以使用匿名对象
2.将匿名对象做为实参传递给一个函数调用,比如程序只有一个get someone函数要接收一个person类对象做为参数
比如:public static void getSomeOne(person p){......}就可以用get SomeOne(new persong());来调用这个函数
实现类的封装性:
为了对数据的保护,不让人随意修改数据那么我们就需要对数据进行保护。
怎么样对一个类的成员实面保护呢?
只需要定义一个类的成员使用private关键字说明空上成员的访问权限这个类成了私有成员了那么就只能被这个类的其他成员调用 。而不能被其他类中的方法所调用
class persondemo
{
private int age;
public void shout()
{
System.out.println(age);//这一句调用 没有错因为他们是在一个类里面所以本类调用 是可以的也就是说封装后只能是这个类才可以调用 他其他类不可以调用 他所以下面会报错
}
}
class person
{
public static void main(String[] args)
{
new person().age=18;//这里会报错因为上面权限私有了但仍然调用所以报错这里使用了访问其他类的格式 对象.对象成员这是必要格式但是私有了所以还是失败了
}
}
当然private关键字是私有的意思那么大家 也就应该明白 了public关键字的意思公有如果用public修饰那么这些个成员就变成 了仅有的那么就可以在任意类中访问了
要在不一个类的外部访问这个类的成员那么就要用 对象.对象成员 的格式
为了实现良好的封装性通常都 会将类成员声明为private再通过 public方法来对这个变量进行访问
对变量的定义一般都有读取和赋值操作分别定义两个方法来实现这两个操作getXxx()(xxx这里表示要访问的成员变量的名字)setXxx()
我们通过将类的成员变量声明为私有再提供一个或多个公有的方法实现对该成员的变量的访问或修改,这个就叫封装。
封装的目的:
1.隐藏类的实现细节;
2.让使用者只能通过事先制定好了的方法来访问数据。可以方便控制逻辑,限制对属性的不合理操作。
3.便于修改,增强代码的可维护性
4.可进行数据检查
class person { private int age; public void setAge(int i) { if(i<0||i<200) return; age=i } public int getAge() { return age; } } } public calss testpreson { public static void main(String args[]) { person p=new person(); p.setAge(3);//利用对象.set属性名给age这个属性赋值
p.setAge(18); System.out.println(p.getAge());//这里利用对象.get属性名()这个方法读取了person类的成员变量 } }
这里一个封装利用public修饰来调用private的一个示例。
一个类就是一个模块,我们仅仅公布了需要让外界知道的内容,而隐藏其他的内容。在进行程序的设计的时候我们应该尽量的避免一个模块直接修改或操作另一个模块的数据
模块设计 追求的是 强内聚。弱耦合。 我 们不需要做太多的时候 我们不需要知道他的过程我们只需要发布命令和知道结果就好了如果说我们什么都作了那不就是面向过程 了么
构造函数:
构造函数的定义与作用:
什么是构造方法?
就是创建一个对象就自动调用这个对象的成员变量一次
特点:
它具有与类相同的名称’
它不含有返回值
它不能在方法是使用return语句返回一个值
作用:我们可以运用来做一个初始化。因为当一个类实例对象刚产生时这个类就会自动调用,我们可以在这个方法 中加入要完成 初始化工作的代码。这就好像规定第个人一出生就必须洗澡一样所以我们就在人的构造方法中加入完成洗澡的代码于是第产生一个人他就会洗澡了。
构造方法 的名称 为什么要和类的名称相同呢?
因为构造方法 由java编译器负责调用,而编译器必须 知道 哪 一个才是构造方法,采用与类同名的方式应该是最简单合理 的
注意:
在构造方法 里不含返回 值的概念是不同于void的对于 public void person()这样就不是构造方法了变成普通的方法,很多人都 会犯这样的错误,在定义 里加了void就不会再自动调用了。构造方法就是权限 类名(){这里面可以加条件和执行语句}加一个私有的变量属性。
构造方法重载(同名构造方法):
上面多定义 一个构造方法这就是函数的重载。他们和一般的构造方法一样,具有不同个数或不同类型的参数
编译器就可以跟据这一点判断出用NEW关键字产生对象时应该调用那个构造函数
class person { private String name="unknown"; private int age=18; public person()//这就是最简单的一个构造方法
{
System.out.println("constructor1 is calling"); } public person(String n)//这也是一个构造方法一般构造方法都是以这样的格式存在的。这里是对产生的对象进行了赋值操作赋值的是一个字符串
{ name=n; System.out.println("constructor2 if caling"); System.out.println("name is"+name); } } class testperson { public static void main(String[] args) { person p=new person(); p.shout();//这里直接调用了上面的第一个构造方法
person p1=new person("kevin");//这里调用了第二个构造方法。
p1.shout(); } }
这里定义了一个构造方法重载里面有两个同名的构造方法这就是构造函数重载。构造函数类似
构造方法的一些细节:
1.在jav的每个类里面都 至少有一个构造方法,如果程序员没有在一个类里面定义构造方法系统会自动为这个类产生一个默认的构造方法,这个默认构造方法有参数在其方法 体中也没有任何 代码,即什么 都 不做 当然系统默认的方法也不能满足用户的需求所以我们就需要人为的定义方法人为定义了就不再使用系统默认的方法
Construct类的两种写法
class Construct { } class Construct { public Construct(){} }
class Construct { int age; public Constrct(int x) { age=x; } }
这里就是定义了一个对成员变量赋初值 的构造方法。该方法 有一个形式参数
注意:一旦定义了一个有参数的构造方法那么就必须要再定义一个无参数的构造方法因为定义一个有参数的构造方法系统就将不再提供一个默认的构造方法了
否则会报错
class testdemo { public static void main(String[] args) { Construct c=newConstruct(); } }//这里就是一个错误的因为定义了有参数的构造方法导致的结果
2.声明构造方法时可以使用private修饰符么?
不可以使用。因为private是私有的不可以被外部调用。可见一般构造方法都是public的因为他们在对象产生时公被 系统 自动 调用。