Java面向对象
一、面向对象概念
面向对象:面向对象是相对面向过程而言,面向对象和面向过程都是一种思想。面向过程强调的是功能行为。面向对象:将功能封装进对象,强调具备了功能的对象。面向对象是基于面向过程而言的。
神马是面向对象(面试)?
答:1、特点:是一种思想,是复杂的问题简单化,让角色从执行者变为指挥者。2、例子:结合实际场景。
二、人开门
人
{
开门(门){
门.开();
}
}
门
{
开(){
操作门轴;
...
}
}
三、面向对象的特征
面向对象三个特征:封装,继承,多态。
以后开发:其实就是找对象使用,没有对象就创建一个对象。
简单的说:找对象,建立对象,使用对象,维护对象的关系。
四、类和对象的关系
类:就是对现实生活中事物的描述。
对象:就是这类事物实实在在存在的个体。
现实生活中的对象:张三,李四。
想要描述:提取对象中共性内容。对具体的抽象。
描述时:这些对象的共性有:姓名,年龄,性别,学习Java功能。
在Java中
描述:就是class定义的类。具体对象就是对应java在堆内存中用new建立的实体。
描述事物:就是在描述事物的属性和行为。
需求:描述汽车。(颜色,轮胎数)
类与对象的关系如图
可以理解为:
类:就是图纸。
堆内存中对象:就是汽车。
属性对应的是类中的变量,行为对应的是类中的函数(方法)。
其实定义类,就是在描述事物,就是在定义属性和行为。属性和行为共同成为类中的成员(成员变量和成员方法)。
class Car
{
//描述颜色
String color = "红色";
//描述轮胎数
int num = 4;
//运行行为
void run(){
System.out.println(color+".."+num);
}
}
class CarDemo
{
public static void main(String []args){
//生产汽车,在java中通过new操作符来完成。
//其实就是在堆内存中产生一个实体
Car c = new Car();
//c就是一个类类型变量。记在类类型变量指向对象。
c.run();
}
}
需求:将已有车的颜色改成蓝色。
指挥该对象做事,在java中指挥方式是:对象.对象成员。
class Car
{
String color = "红色";
int num = 4;
void run(){
System.out.println(color+".."+num);
}
}
class CarDemo
{
public static void main(String []args){
Car c = new Car();
//将汽车的颜色改为蓝色。
c.color = "blue";
c.run();
}
}
例:
class Car
{
String color = "红色";
int num = 4;
void run(){
System.out.println(color+".."+num);
}
}
class CarDemo
{
public static void main(String []args){
Car c = new Car();
c.num =5;
Car c1 = c;
c1.color = "green";
c.run();
}
}
内存图示:
五、成员变量和局部变量
作用范围:成员变量作用于整个类中。局部变量作用于函数中,或语句中。
在内存中的位置:成员变量在堆内存中,因为对象的存在,才在内存中存在。局部变量存在栈内存中。
六、匿名对象
神马是匿名对象?
匿名对象:是对象的简化形式。
class Car
{
String color = "红色";
int num = 4;
void run(){
System.out.println(color+".."+num);
}
}
class CarDemo
{
public static void main(String []args){
//匿名对象
new Car.num = 5;
new Car.color = "blue";
new Car().run();
}
}
内存图示:
匿名对象使用方式一:当对对象的方法只调用一次时,可以用匿名对象来完成,这样写比较简化。
匿名对象使用方式二:可以将匿名对象作为实际参数进行传递。
注:如果对一个对象进行多个成员调用,必须给这个对象起个名字。
需求:汽车修配厂,对汽车进行改装,将来的车都改成黑色,三个轮。
class Car
{
String color = "red";
int num = 4;
void run(){
System.out.println(color+".."+num);
}
}
class CarDemo
{
public static void main(String []args){
Car q = new Car();
show(q);
}
public static void show(Car c){
c.num = 3;
c.color = "black";
c.run();
}
}
内存图示:
class Car
{
String color = "red";
int num = 4;
void run(){
System.out.println(color+".."+num);
}
}
class CarDemo
{
public static void main(String []args){
show(new Car());
}
public static void show(Car c){
c.num = 3;
c.color = "black";
c.run();
}
}
七、封装
神马是封装?
封装:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。
好处:将变化隔离,便于使用,提高重用性,提高安全性。
科普:函数是最小的封装体。
private关键字:私有,权限修饰符,用于修饰类中的成员(成员变量和成员函数)。被私有化的成员只在本类中有效。
常用方式之一:将成员变量私有化,对外提供对应的set和get方法对其进行访问,提高对数据访问的安全性。
class Person
{
/*
将age私有化以后,类以外即使建立了对象也不能直接访问,但是人应该有年龄,就需要在Person类中提供对应访问age的方式。
规范写法:
设置—>set
获取—>get
一个成员变量有两个访问方式。
*/
private int age;
public void setAge(int a){
if(a>0&&a<130){
age = a;
speack();
}
else{
System.out.println("nono");
}
}
public void speack(){
System.out.println("age = "+age);
}
}
class Demo
{
public static void main(String []args){
Person p = new Person();
p.setAge(20);
}
}
注:私有仅仅是封装的一种表现形式。
之所以对外提供访问方式,就是因为可以在访问方式中加入逻辑判断等语句,对访问的数据进行操作。提高代码的健壮性。
八、构造函数
构造函数特点:
1、函数名与类名相同。
2、不用定义返回值内容。
3、不可以写return语句。
作用:给对象进行初始化。
注意:
1、默认构造函数的特点。
2、多个构造函数是以重载的形式存在的。
3、对象一建立就会调用与之对应的构造函数。
构造函数的小细节:当一个类中没有定义构造函数时,那么系统会默认给该类加入一个无参数的构造函数。当类中定义了构造函数后,默认的构造函数就没有了。
构造函数和一般函数的区别:构造函数和一般函数在写法上有不同,在运行上也有不同,构造函数是在对象一建立就运行。给对象初始化。而一般函数是对象调用才执行,是给对象添加对象具备的功能。一个对象建立,构造函数只运行一次,而一般函数可以被该对象调用多次。
什么时候定义构造函数呢?
答:当分析事物时,该事物存在具备一些特性或者行为,那么将这些内容定义在构造函数中。
class Person
{
private String name;
private int age;
Person(){
show();
}
Person(String n){
name = n;
show();
}
Person(String n,int a){
name = n;
age = a;
show();
}
public void show(){
System.out.println("name = "+name+",age = "+age);
}
public void cry(){
System.out.println("crying...");
}
//构造代码块
{
cry();
}
}
class Demo
{
public static void main(String []args){
Person p1 = new Person();
Person p2 = new Person("lisi");
Person p3 = new Person("wangwu",10);
}
}
九、构造代码块
作用:给对象进行初始化。对象一建立就运行,而且优先于构造函数执行。
和构造函数的区别:构造代码块是给所有对象进行统一初始化。而构造函数是给对应的对象初始化。
应用:构造代码块中定义的是不同对象共性的初始化内容。(面试)
注:如果局部中有相同的变量,那么该变量都是局部变量,如果没有,则找成员中的。
class Person
{
private String name;
private int age;
Person(){
show();
}
Person(String name){
//因为局部变量里有name变量,所以这两个都是局部变量,而不会访问到类中的成员变量。
name = name;
show();
}
Person(String name,int age){
//因为局部变量里有name和age变量,所以这两个都是局部变量,而不会访问到类中的成员变量。
name = name;
age = age;
show();
}
public void show(){
System.out.println("name = "+name+",age = "+age);
}
public void cry(){
System.out.println("crying...");
}
}
class Demo
{
public static void main(String []args){
Person p3 = new Person("wangwu",10);
}
}
所以:
解析:name和age里面只有初始化值,构造函数中的局部变量name和age没有赋值给成员变量。因为成员变量名和局部变量名相同,函数里面的局部变量又赋值给自己,而不是给成员变量。所以出现上图只有初始化值。
解决办法:引入this关键字
class Person
{
private String name;
private int age;
Person(){
show();
}
Person(String name){
//引入this关键字,调用了本类对象的name,也就是成员变量name。
this.name = name;
show();
}
Person(String name,int age){
//引入this关键字,调用了本类对象的name和age,也就是成员变量name和age。
this.name = name;this.age = age;
show();
}
public void show(){
System.out.println("name = "+name+",age = "+age);
}
public void cry(){
System.out.println("crying...");
}
}
class Demo
{
public static void main(String []args){
Person p3 = new Person("wangwu",10);
}
}
十、this关键字
this到底代表的是什么呢?
this关键字:代表本类的对象。代表它所在函数所属对象的引用。
简单的说:哪个对象在调用this所在函数,this就代表那个对象。
this的应用:当定义类中功能时,该函数内部要用到调用该函数的对象时,这时用this表示这个对象。但凡本类功能使用到了本类对象,都用this表示。
class Person
{
private String name;
private int age;
Person(String name){
//因为局部变量里有name变量,所以这两个都是局部变量,而不会访问到类中的成员变量。
this.name = name;
show();
}
Person(String name,int age){
//因为局部变量里有name和age变量,所以这两个都是局部变量,而不会访问到类中的成员变量。
this.name = name;
this.age = age;
show();
}
public void show(){
System.out.println("name = "+name+",age = "+age);
}
//比较年龄
public boolean comparte(Person p){
//本人年龄与另一人的年龄比较
return this.age==p.age;
}
}
class Demo
{
public static void main(String []args){
Person p1 = new Person("wangwu",10);
Person p2 = new Person("lisi",10);
Person p3 = new Person("zhangsan",12);
System.out.println(p1.comparte(p2));
System.out.println(p1.comparte(p3));
}
}
代码优化:
Person(String name){
this.name = name;
show();
}
Person(String name,int age){
this.name = name;
this.age = age;
show();
}
发现代码有重复,为了避免这类问题。可以引用this语句简化代码。
this语句:用于构造函数间进行相互调用。
class Person
{
private String name;
private int age;
Person(String name){
this.name = name;
}
Person(String name,int age){
//采用this语句,将name的值传给构造函数Person(String name)。
this(name);
this.age = age;
show();
}
public void show(){
System.out.println("name = "+name+",age = "+age);
}
//比较年龄
public boolean comparte(Person p){
//本人年龄与另一人的年龄比较
return this.age==p.age;
}
}
class Demo
{
public static void main(String []args){
Person p1 = new Person("wangwu",10);
Person p2 = new Person("lisi",10);
Person p3 = new Person("zhangsan",12);
System.out.println(p1.comparte(p2));
System.out.println(p1.comparte(p3));
}
}
注:this语句只能定义在构造函数的第一行。因为初始化要先执行。
class Person
{
Person(){
this("hah");
}
Person(String name){
this();
}
}
这种情况不允许出现,相当于死循环。