面向对象
一、面向对象
1、面向对象的概念的理解
面向对象将功能进行了封装,强调具备了功能的对象。面向过程强调的是功能行为。
2、类
我们在开发中,可以尝试通过名词提炼法得到对象与对象的关系。比老师在视屏中说开发是找对象,建立对象,使用对象并维护对象之间的关系的一种工作
那么类就是对现实生活中事物的描述,对象是实实在在的个体,我们可以在java中通过new关键字在堆内存中创建对象。比如说,人类是一个类,他描述了人类的特征,而我就是人类的对象。我具有人类的所描述的特征。在java类中人类可以是这样的——他具有一些特征,比如人类的外形(四肢,头发,五官等等),而具体到我们个体就是对象了。
3、类成员
(1)、成员变量和局部变量的不同
a、作用范围不一样b、成员变量和局部变量在内存中的位置也不一样。成员变量在堆内存中,因为对象的存在而在内存中存在,局部变量存在在栈内存中。
(2)、函数的调用
a、想在主函数中调用其他函数,有两种方式。第一是将这个方法设为静态的。当
这个方法不能是静态的时候,当然或者这个方法是非静态更好些时,我们可以使用第二种方法。第二中方法是:在主函数中建立本类对象,然后使用对象调用这个非静态的方法。
b、代码示例
class car{
String color;
int num;
void run( ) {
System.out.println(color+”…..”+num);
}
//你看,run方法不是静态的,但我可以这样调用它
public static void main( String[] args){
Car c = new Car( );
c.num = 10 ;
}
}
(2)、关于主函数
解析:
a、访问权限最大。public
b、没有返回值。void
c、参数。String[] args
特点:
a、是一个特殊的函数,作为程序的入口,可以被jvm调用。
b、格式固定。public static void main(String[] args){}
c、main不是关键字,是一个可以jvm识别的特殊单词。
d、传参
jvm在调用主函数时,传入的是new String[0]。我们也可以给主函数传值。如:java 类名 haha hehe heihei 。
e、一个类中只能有一个主函数。一个java文件中,可以在多个类中写主函数。
4、匿名对象
(1)、简化代码
当对象只调用一次方法时(当对象需要多次调用方法时,必须给对象命名),可以简化代码。
(2)、匿名对象作为参数传递。
class {
public static void main(String[] args){
show(new Car( ));
}
public static void show(Car c){
c.num = 6 ;
c.color = “yellow” ;
}
}
这段代码需要知道的一点是,我们在主函数中调用了show方法,并传入了一个匿名对象,但这个匿名对象,是有名字的,它的名字是c 。
5、构造函数和构造代码块
(1)、构造函数的3个特点,
a、函数名和类名一致,
b、而且没有返回类型,
c、对象一建立就会调用且只调用一次与之对应的构造函数(而且构造函数是可以私有化的)。当一个类没有构造函数时,系统会添加一个默认的空参数的构造函数,如果自己定义了构造函数,系统就不再添加
(2)、构造代码块
构造代码块优先于构造函数执行,定义的是不同对象共性的初始化内容。构造函数和构造代码块的区别:构造函数是给对应的对象初始化,而构造代码块是给所有的对象初始化。比如说有一个类,有两个构造函数,而参数不同,只有在建立对应的对象时被调用,而构造代码块只要是用这个类建立对象都会执行。
二、c关键字this 和static
1、this关键字
局部变量可以给局部变量赋值,诸如name = name是可以的.
(1)、构造函数中的this。
a、在构造函数中我们常常要把参数的值赋给成员变量的name,而不是局部变量中的name,这时就要这样写,this.name = name ;这时 this 标识了name的所属是成员变量。
b、this可以用于构造函数间的互相调用,如this(name),表示调用了参数为name的构造函数。需要注意的是死循环的情况,还有用this语句只能写在构造方法的第一个语句位置
c、另外一般函数是不能调用构造函数的,因为this()这种写法不能用在一般函数中。
d、示例代码
class Person{
private String name;
private int age ;
Person(){}
Person(String name){
this.name = name ;
}
Person(String name,int age){
this(name)
//——>相当于Person(name);但遗憾的是在构造函数中不支持这种写法
this.name = name ;
this.age = age ;
}
}
(2)、方法中的this
a、this代表它所在函数所属对象的引用。比老师说的是那个对象在调用this所在的函数,this就代表哪个对象。 当定义类中功能时,该函数内部要用到调用该函数的对象时,这时用this。但凡本类功能内部使用了本类对象,都用this表示。(this是一个变量,对象调用有this的方法的时候,就把自己的地址值赋给了this) ex:
b、示例代码
class Person{
private String name ;
private int age ;
Person( String name,int age){
this.name = name ;
this.age = age ;
}
public boolean compare( Person p){
return this.age == p.age;
}
}
2、静态static,
(1)、static关键字。static用于修饰成员(成员变量和成员函数)。当成员被静态修饰后,就多了一个调用方式,除了可以被对象调用外,还可以直接被 类名调用。
(2)、static在内存中的特点:
a、随着类的加载而加载。随着类的消失而消失。说明它的生命周期长。而像未被static修饰的成员变量,没有对象是不会被加载的。有了static修饰,只要类加载了,在内存中就存在了。
b、优先于对象存在。对象是后存在的。
c、被所有对象所共享,
d、可以直接被类名调用。
(3)、静态使用要点
a、静态方法不能访问非静态成员。因为静态方法存在的时候,非静态的成员还没有存在。
b、静态中不能定义this,super关键字。因为静态优先于对象存在,所以静态方法中不可以出现this。
(4)、什么时候使用静态
我们什么时候定义静态变量呢?当对象中的属性具有共享数据时(是共享数据而不是共享属性)。对象中特有的数据要定义成非静态。
什么时候定义静态函数呢?当功能内没有访问到非静态数据(非静态的属性)。该功能可以定义成静态的。
(5)、静态的应用
工具类。我们写了一个ArrayTools。虽然可以通过建立对象使用类找给中的方法。不过,对象是用来封装数据的,可是ArrayTools对象昂并未封装特有数据,操作数组的每一个方法都没有用到ArrayTools对象中的特有数据。这时就考虑到为了让程序更严谨,是不需要对象的。所以可以让ArrayTools中的方法都定义成static的。直接通过类名调用即可。为了更为严谨,可以将对象的构造函数私有化,让其不可以创建对象。
静态代码块。静态代码块的格式static{ }。特点:随类的加载而执行,只执行一次。作用是对类进行初始化。
有几个点要注意1String st = null;这是类是没有加载的。因为没有用到类中的内容。2通过new创建对象时,就已经使用到了类中的内容,,被用到的内容必然有构造函数。3静态代码块,非静态代码块,构造函数的执行顺序依次是:静态代码块——>非静态代码块——>构造函数。它们分别给类,对象,对应对象进行了初始化,
(6)、静态的好处和弊端
可以直接被类名调用,使用方便。但生命周期长,较占用内存。
三、实例变量和类变量的区别
有两点:1存放位置。实例变量存在于堆内存中,类变量存在于方法区中。2生命周期。类变量生命周期最长,类消失才会消失。而实例变量随对象的消失而消失。
四、对象初始化和调用成员
五、封装、继承和多态
1、封装(encapsulation)
封装就是隐藏对象的属性和实现细节,仅对外提供公共访问方式。
封装的好处有4点:1将变化隔离,2便于使用,3提高重用性,4提高安全性
封装的原则:把不需要对外提供的属性等都隐藏起来,我们只需要对外提供公共方法就可以了。在提供给外界的访问方法中,可以加入逻辑判断等语句,对访问的数据进行操作。这样提高了代码的健壮性。
封装不是私有,私有是封装的一种体现形式。
2、继承和聚集关系
继承的意义:1提高代码的复用性2让类与类之间产生了关系。有了这个关系,才有了多态的特性。
需要注意的是,千万不要为了获取其他类的功能,简化代码而去继承。必须是类与类之间有所属关系才可以继承。所属关系is a。
java语言中,只支持单继承,不支持多继承。因为多继承容易带来安全隐患,当多个父类中定义了相同功能,当功能内容不同时 不确定要运行哪一个。但是java保留这种机制。并用另一种体现形式来完成表示,就是多实现。
java支持多层继承,也就是一个继承体系。
使用思想:查阅父类功能,创建子类对像。
聚集关系has a 。分聚合和组合。聚合例如球员和球队,组合例如手和人。
子父类中成员的特点。类中成员主要有变量,函数,构造函数。对于变量来说,继承时如果子类中出现非私有的同名成员变量时,子类要访问本类中的变量,用this,子类要访问父类中的同名变量,用supper。supper的使用和this的使用几乎一致,this代表的是本类对象的引用,supper代表的是父类对象的引用。对于函数,会发生覆盖