面向对象的特点:它是一种思想,它让复杂的问题简单化,它把执行者变成了指挥者。
结合实际场景来说:其实面试官你就是在用面向对象的思想在思考问题,为什么这么说?因为公司业务蒸蒸日上,需要招更多的人来完成项目,所以才在这里招聘人员,你需要找一些具备专业编程经验的人,来 帮公司完成工作,那么我就是那个对象,因为我具备专业编程能力,你就是那个指挥者,指挥我来做事,至于我怎么去完成编程任务,你是不需要去知道,你只要结果了就可以了,这其实就是把你之前的工作简化了,你不必再事必躬亲了。这就是面向对象思想的体现。
a) 类到底是什么?
类就是对一类事物的归纳。
类就是对现实生活中事物的描述,描述中包含了该类事物的共性内容。
Class Car()
{
Int num;
String color;
Void run(){}
}
在类中定义的变量和函数都称为类中的成员。
成员:
成员变量---属性
成员函数---行为
b) 什么是对象?
对象就是该类事物实实在在存在的个体。
:现实生活中的对象:张三、李四
想要描述:提取对象中的共性内容,对具体的抽象。
描述时:这些对象的共性有姓名年龄性别学习java的功能。
对象也可以理解为其实就是个容器,用来存储更多的数据,存储的都是每一个对象特有的数据,而类就是这些数据所属的属性。
毕向东视频的小车问题:
Class Car
{
String color="red";
Int num=4;
Run()
{
System.out.println(color+""+num);
}
}
Class CarDemo
{
Public static void main(String[] args)
{
Car c=new Car();
C.color="bule";
C.num=5;
C.run();m
Car c1=new Car();
C1.num=8;
C1.color="green";
C1.run();
}
}
![](https://img-my.csdn.net/uploads/201208/29/1346218657_3146.png)
6、成员变量和局部变量的区别:
1、源代码中定义位置不同:
成员变量:定义在类中,在整个类中有效。
局部变量:定义在函数中,在局部范围内有效。
简单一句话:作用范围不一样,成员变量作用于整个类中,局部变量作用于函数中,或者语句中。
2、在内存中的位置和事件不同:
生命周期不同:
成员变量:随着对象的创建的而出现在堆内存中,随着对象被回收而消失。
局部变量:随着变量所属局部区域的运行,而出现在栈内存中,随着所属区域运行结束而释放。
3、变量使用的初始化:
成员变量:因为堆内存中都有默认初始化值,对于引用型变量默认值就是null;
局部变量:因为在栈内存中都没有默认初始化值,必须手动初始化后才可以参与运算。
7、匿名对象:
即没有名字的对象,简化书写用的。
基本使用:
1、当对对象的方法只调用一次时,可以用匿名对象来完成
这样写比较简化,如果对一个对象进行这个成员的调用,必须给这个对象起个名字
2、可以将匿名对象作为实际参数进行传递。一旦对对对进行多个成员操作时。必须要对对象起个名字。
Main()
{
Show(new Car())
}
Public static void show (Car c)
{
C.num=3;
C.color="back";
C.run();
}
8、面向对象三个特征:
封装:
是指隐藏对象的属性和实现细节,仅对外提供公共访问方式,凡是面向对象必须有封装性。
特点:
将变化隔离
便于使用
提高复用性
提高安全性
原则:
1、将不需要对外提供的内容都隐藏起来。
2、把属性都隐藏,提供公共方法对其访问。
在代码中的体现:
1、将成员变量都私有化,并通过共有的方法对其进行访问,这两个方法是:setXxx\getXxx
2、只要不准备对外提供的全部都封装起来,
私有仅仅是封装的一种表现形式,函数是最小的封装体。
Class Person
{
Private int age;//为了不让其他程序直接访问age属性,避免错误的数据,可以使用一个关键字来完成private私有,它是一个权限修饰符。private是权限等级最小的,public最大
Public void setAge()//对外提供函数是可以控制你输入的参数。
//一个成员变量通常对应的两个方法、
{
If(a>140||a<0)
{
Age=a;
Speak();
}
Else
System.out.println();
}
Public void getAge()
{
Return age;
}
Void speak()
{
Sop();
}
}
Class PersonDemo
{
Public static void main(String[] args)
{
Person p=new Person();
P.age=-20;//错误数据是因为对象直接访问age属性造成的。
P.speak();
}
}
总结:之所以对外提供访问方式,就是因为可以在访问方式中加入逻辑判断等语句
对访问的数据进行操作,提高代码的健壮性。凡是set开头的返回值类型是void,get开头的跟它的返回值类型一致。
Day07总结:
1、构造函数:
特点:1、函数名和类名相同
2、不用定义返回值类型
3、不可以写return语句
作用:
创建一个对象都会执行这个构造函数,所以构造函数的作用给对象进行初始化。
每一个对象的创建,都必须要通过对应的构造函数进行初始化,对象不初始化是不能用的。
注意
没有定义类的情况下有一个默认的空参数的构造函数,方便该类的对象进行初始化。
如果在类中定义了具体的构造函数,那么默认的空参数构造函数就没有了。
2、构造函数和一般函数的区别:
1、格式:
两种函数的格式不同:
构造函数:修饰符 类名(参数列表){}
一般函数:修饰符 返回值类型 自定义函数名(参数列表){}
2、运行方式
构造函数:构造函数是在对象已经建立就执行对应的构造函数,给对象进行初始化。
一般函数:对象创建后,再调用一般函数。
3、作用不同
构造函数:是对对应对象进行初始化的,叫做对象已建立时要做什么事情?
一般函数:给对象提供更多的功能,方便与对象的调用。
4、调用次数
构造函数:对象创建时,就调用一次,因为初始化动作最先执行,只执行一次
一般函数:对象创建后,可以被多次调用。
3、什么时候定义构造函数呢?
分析具体事务时,该事务已经存在,就应该具备一些属性值,或者行为,那么将这些内容都定义在构造函数中。(列:婴儿刚出生都具有哭的属性值,那么就可以定义在构造函数中)
一个类中构造函数可以有多个,而且是以重载的形式存在。
小细节:
a) 构造函数中是可以写return语句的,因为当构造函数中存在判断的时,可以写return,作用就是结束语句。
b) 同样构造函数是可以添加void的,这样的话就不是构造函数了,就成为了一般函数了。
3 构造代码块:
作用:给对象进行初始化。
对象一建立就运行,而且优先于构造函数执行。
和构造函数的区别:
构造代码块是给所有对象进行统一初始化,
而构造函数是给对应的对象初始化。
构造代码快中定义的是不同对象共性的初始化内容。
代码示例:
class Person
{
private String name;
private int age;
/*
构造代码块。
*/
{
//System.out.println("person code run");
cry();
}
//构造函数
Person()
{
System.out.println("A: name="+name+",,age="+age);
}
/**/
Person(String n)
{
name = n;
System.out.println("B: name="+name+",,age="+age);
//cry();
}
Person(String n,int a)
{
name = n;
age = a;
System.out.println("C: name="+name+",,age="+age);
//cry();
}
public void cry()
{
System.out.println("cry......");
}
}
class PersonDemo2
{
public static void main(String[] args)
{
Person p1 = new Person();
Person p2 = new Person("lisi");
}
}
this关键字:
当成员变量和局部变量重名的时候,为了区分这种情况我们可以使用一个关键字来完成,就是this
它代表的是什么呢?This关键字代表的就是一个对象的引用。
代表哪个对象? 代表当前对象,它自己不是对象,只是一个引用。
只要是成员,必须被对象所调用。
总的一句话:定义功能时,如果功能中用到了本类对象,这时就使用this这个关键字
7、this关键字:
当成员变量和局部变量重名的时候,为了区分这种情况我们可以使用一个关键字来完成,就是this
它代表的是什么呢?This关键字代表的就是一个对象的引用。
代表哪个对象? 代表当前对象,它自己不是对象,只是一个引用。
只要是成员,必须被对象所调用。
总的一句话:定义功能时,如果功能中用到了本类对象,这时就使用this这个关键字表示这个对象。
用毕老师的话说
哪个对象在调用this所在的函数,this就代表哪个对象
总结:构造函数之间的调用,构造函数中调用其他构造函数的this语句必须定义在构造函数的第一行,因为构造函数是用来初始化的。初始化的动作必须先执行。
7、static静态关键字
1、它是一个修饰符,只能修饰成员(成员变量和成员函数)
2、被static修饰的成员变量的数据,可以被所有的对象们共享。
3、被静态修饰的成员多了一种调用方式,就是除了被对象调用以外,还可以被类名直接调用,类名.静态成员。
4、静态之所可以被类名调用,那是因为静态成员是随着类的加载而加载进内存的。非静态的特点随着对象的加载而加载。
5、静态优先于对象加载进内存,所以不能访问对象的内容,但是对象可以访问它的内容。
6、被静态修饰的成员为共有数据,对象里面自身村存储的是特有数据。
Eg:饮水机是共有的,但是喝水的杯子是特有的。
怎么理解共性?只要在描述事物的时候发现这特点是大家都有的。
10、静态的使用注意事项:
1、静态成员函数只能访问类中的静态成员,不能访问非静态的。非静态方法可以访问静态方法。
2、静态方法中不可能定义this spuer关键字,因为This代表的是对象,但是静态加载的时候都没有对象存在。
主函数是静态的。
成员变量和静态变量的区别:
1、成员变量只能被对象所调用,静态成员变量除了可以被对象调用还可以被类名调用
2、成员变量也称为对象变量或者实列变量。因为成员变量是被对象使用的变量。静态变量也称为类变量。
3、成员变量是随着对象的出现而出现,随着对象的回收而消失。静态变量随着类的加载而加载,随着类的消失而消失。
一个代码中一个静态都不写是可以的,不写静态是因为静态的生命周期特别长,但是我们要考虑到代码的严谨性是需要写一些静态的。
什么时候使用静态?
成员变量:如果该变量的数据值每个对象都一样。就将其静态修饰,否则就是非静态。
成员函数:如果功能中没有访问到对象中的特有数据,那么就需要将该函数定义成静态,因为创建对象调用除了浪费堆内存空间没有意义。
静态代码块:
格式:
Static
{
静态代码块中的执行语句。
}
特点:随着类的加载而加载而且只执行一次,类一加载静态代码块就执行。
作用:用于给类进行初始化的,注意区别构造代码块:给对象都进行初始化。
1、单列设计模式:
a) 什么是设计模式:解决某一类问题最行之有效的方法。
b) 单列设计模式:解决一个类在内存中只存在一个对象。
1 为了避免其他程序过多的建立该类对象。先控制禁止其他程序建立该类对象
2 还为了让其他程序可以访问到该类对象只好在本类中自定义一个对象。
3 为了方便其他程序对自定义对象的访问可以对外提供一些访问方法。
怎么代码体现:
1、将构造函数私有化。
2、在类中创建一个本类对象。
3、提供一个方法可以获取到该类对象。
对于事物该怎么描述,还怎么描述。
当需要将该事物的对象保证在内存中唯一时,就将以上的三步加上即可。
饿汉式:
Class Single 恶汉式:定义单列时,建议使用恶汉式。
{
Private int num;
Public void setNum(){}
Public int getNum(){}
Private static Single s=new Single();
//为什么要私有?对成员数据可控?因为方法很有可能有参数,所以不用把S暴露出去,加private;
Public static Single getIntnstance()
{
Return s;
}
}
单列延迟加载方式:
懒汉式:增加了一个判断
//只有对象被调用的时候才会被加载,才被初始化,称之为懒汉式。
Class Single
{
Private Single(){}
Private static Singel s=null;
Public static Single getIntance()
{
If(s==null)
S=new Single();
Return s;
}
}
继承:
a) 概述:多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无序再去定义这些属性和行为,只要继承那个类即可。
b) 那多个类成为子类,单独这个类成为父类或者基类超类,
c) 子类可以直接访问父类重的非私有的属性和行为。
d) 通过extends关键字让类与类之间产生继承关系。
特点:
1、继承的而出现提高了代码的复用性。
2、继承的出现让类与类之间产生了关系,提供了多态的前提。
3、Java支持单继承,对于多继承,java保留了这种机制并进行了改良,避免了多继承调用时的不确定性。
什么时候使用继承?
当事物之间存在着所属关系时,就可以使用继承,
所属:xxx是yyy的一种,即x继承y
如果A真继承了B,B中的锁有的功能是不是A都具备了。
继承子父类中的成员变化。
1、成员变量:
a) 当子父类中出现同名的成员变量时,可以使用super关键字来区分,父类的成员变量。
b) Super和this用法很相似,this代表的是本类的对象,super代表父类的所属的空间,
c) 先有父类在有子类。面试中会出现,开发中几乎没有,因为父类的成员都是从下到上抽取的,子类中还保留相同的变量干嘛?
2、成员函数
当子父类出现一模一样(返回值、函数名、参数列表全部相同)的函数时,就会出现调用时运行子类的方法的情况。
这种情况,形象成为覆盖或者重写或者覆写。
什么时候用覆盖?
当对一个类中的功能的内容进行重新定义时,可以定义该类的子类,并保留父类中的功能声明,重新定义功能内容,并建立子类对象调用该功能。
实现代码:
/*
当子父类中出现一模一样的函数时,就会出现调用时运行子类的方法的情况。
这种情况,形象的称为 覆盖或者重写或者叫做覆写 override。
什么时候用覆盖?
当对一个类中的功能的内容进行重新定义的时,可以定义该类的子类,并保留父类中的功能声明,
重新定义功能内容。并建立子类对象调用该功能。
覆盖小细节:
1,子类方法覆盖父类方法时,权限必须大于等于父类的权限。
2,静态只能覆盖静态,或者被静态覆盖。
构造函数
特点:
在运行时,发现父类构造方法先运行了,然后才是子类构造函数。
原因:是因为子类的所有的构造函数中都有一句默认的隐式语句:super();会默认调用父类重空参数的构造函数。
为什么有super默认语句呢?
因为子类对象在初始化时,必须要到父类先去初始化。
为什么要到父类中去初始化呢?
因为子类继承了父类,可以获取父类中的数据,所以在使用父类数据之前必须要明确父类是如何对自己的成员进行初始化的。
这也是子类一定要访问父类构造函数的原因。所以父类的构造函数有两个作用:1、给本类初始化
如果父类中的没有空参数的构造函数,
那么此时在手动就必须通过super语句或this语句指定要访问父类的构造函数。
注意:super关键字必须定义第一行。任何构造函数中的默认第一句都是super.
面试题:为什么super和this不能再构造函数中同时出现?
为什么super语句必须放在第一行?
因为只有父类初始化完之后才初始化子类。
Object是java中所有类的父类。
额,我发现这么把概念堆在一起,纯属蛋疼。