面向对象是一种思想,它的出现将复杂的问题变得简单,程序员从以前的执行者变成了现在的指挥者。对象有一定的功能。
面向对象三个特征:封装,继承,多态。
以后开发:其实就是找对象使用,没有对象,就创建一个对象。找对象,建立对象,使用对象,维护对象的关系。
类和对象的关系:
类就是对现实生活中事物的描述,对象就是这类事物,实实在在存在的个体。
现实生活中的对象:张三李四。
想要描述:提取对象共性内容。对具体的抽象。描述时,这些对象的共性有:姓名,年龄,性别,学习Java功能。
映射到java中,描述就是class定义的类。具体对象就是对应java在堆内存中用new建立的实体。
//属性对应类中变量,行为对应类中的函数(方法) //其实定义类,就是在描述事物,就是在定义属性和行为 //属性和行为共同成为类中的成员(成员变量和成员方法)。 class Car { //描述颜色 String color = "红色"; //描述轮胎数 int num = 4; //运行行为 void run() { System.out.println(color+" "+num); } } class day05 { public static void main(String[] args) { //生产汽车,在java中通过new操作符来完成 //其实就是在堆内产生一个实体 Car c = new Car();//c就是一个类类型变量,记住,类类型变量指向对象 //需求:将已有车的颜色改成蓝色,指挥该对象做事情。在java指挥方式是:对象.对象成员 c.color = "blue"; c.run(); } }
多个引用指向一个对象.
成员变量作用于整个类中。
局部变量作用于函数中,或者语句中。成员变量都有默认值,可以直接参与运算,局部变量不初始化不能参与运算。
在内存中的位置不同:成员变量在堆内存中,因为对象的存在,才在内存中存在。局部变量在栈内存中。
匿名对象是对象的简化形式。
Car c = new Car();
c.num = 5;
可以简写为
new Car().num = 5;
前两句调用匿名对象属性没意义,第三句调用匿名对象方法有意义.执行第二句时,第一句在堆内存中产生的对象成垃圾,第三句执行时,第二句产生的对象成垃圾。
匿名对象使用方式1:当对对象的方法只调用一次时,可以用匿名对象来完成,这样写比较简化。如果对一个对象进行多个成员调用,必须给这个对象起个名字。
凡是简化的都有局限性。
匿名对象使用方式2:可以将匿名对象作为实际参数进行传递。
show(new Car()); 执行完,堆内存中的对象就成垃圾了。
封装:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式.
好处:将变化隔离;便于使用;提高重用性;提高安全性。
封装原则:将不需要对外提供的内容都隐藏起来;把属性都隐藏,提供公共方法对其访问。
函数和类都是封装。
关键字private :私有,权限修饰符,用于修饰类中的成员(成员变量,成员函数),私有只在本类中有效。外界对象不可能访问到。
class Person { private int age; void speak() { System.out.println("age = "+age); } }
将age私有化以后,类以外即使建立了对象也不能直接访问。但是人应该有年龄,就需要在Person中提供对应访问age的方式.
class Person { private int age; public void setAge(int a) { age = a; } public int getAge() { return age; } void speak() { System.out.println("age = "+age); } }
注意:私有仅仅是封装的一种表现形式。private是最小权限.
之所以对外提供访问方式,是因为可以在访问方式中加入逻辑判断等语句,对访问的数据进行操作,提高代码健壮性。
class Person { private int age; public void setAge(int a) { if(a > 0 && a < 130) { age = a; speak(); } else System.out.println("invalid age"); } public int getAge() { return age; } void speak() { System.out.println("age = "+age); } } class day05 { public static void main(String[] args) { Person p = new Person(); p.setAge(-23); } }
构造函数:
特点1:函数名与类名相同 2:不用定义返回值类型 3:不可以写return语句
对象一建立,就自动调用与之对应的类的构造函数。
构造函数的作用:可以用于给对象进行初始化。
class Person { Person() { System.out.println("peer"); } }
构造函数小细节:当一个类中没有定义构造函数时,那么系统会默认给该类加入一个空参数的构造函数
class Person { Person(){} }
构造函数重载。
class Person { private String name; private int age; Person() { System.out.println("A:name = "+name+" , age = "+age); } Person(String n) { name = n; System.out.println("B:name = "+name+" , age = "+age); } Person(String n, int a) { name = n; age = a; System.out.println("C:name = "+name+" , age = "+age); } public void cry() { System.out.println("cry"); } }
构造函数和一般函数在写法上有不同。
在运行上也不同。构造函数是在对象一建立就运行,给对象初始化。而一般方法是对象调用才执行,给对象添加具备的功能。一个对象建立,构造函数只运行一次,而一般方法可以被该对象调用多次。
什么时候定义构造函数?
当分析事物时,该事物存在具备一些特性或者行为,那么将这些内容定义在构造函数中。
class Person { private String name; private int age; /*构造代码块 作用:给对象进行初始化。 对象一建立就运行,而且优先于构造函数执行 和构造函数的区别: 构造代码块是给所有对象进行统一初始化, 而构造函数是给对应的对象初始化. 构造代码块中定义的是不同对象共性的初始化内容 */ { cry();//即任何人对象一建立就先“哭” } Person() { System.out.println("name = "+name+" , age = "+age); } Person(String n) { name = n; System.out.println("name = "+name+" , age = "+age); } public void cry() { System.out.println("cry"); } } class day05 { public static void main(String[] args) { Person p1 = new Person(); Person p2 = new Person("sr"); } }
运行结果:
cry
name = null , age = 0
cry
name = sr , age = 0
this关键字:看上去,用于区分局部变量和成员变量同名的情况。
this:就代表本类的对象,代表它所在函数所属对象的引用
简单说,哪个对象在调用this所在的函数,this就代表哪个对象.
Person(String name) { this.name = name; } Person p = new Person("sr");
上面的this就代表对象p
this的应用:当定义类中功能函数时,该函数内部要用到调用该函数的对象时,这时用this来表示这个对象。但凡本类功能内部使用了本类对象,都用this表示。
public boolean compare(Person p) { return this.age == p.age; }
this语句:用于构造函数之间互相调用.
this语句只能定义在构造函数的第一行.因为初始化要先执行。
class Person { private String name; private int age; Person(String name) { this.name = name; } Person(String name, int age) { this(name);//调用构造函数 this.age = age; } }
this(name);//调用构造函数
this.age = age;
两句前后不能调换顺序,this必须在第一行.