黑马程序员-----面向对象

来源:互联网 发布:韩国研究生留学知乎 编辑:程序博客网 时间:2024/06/08 05:02
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------1、类与对象之间的关系:类:是对事物的描述。 就是将对象中共性的内容 不断抽取出来的一个抽象描述。对象:是该类事物具体的实体new 对象new的是字节码文件对象,在源代码可以没有person类,但是必须有person类的字节码文件实际使用的是person的字节码文件装载进内存并用他产生了一个堆内存实体对象生命周期的开始对象生命周期开始时,需要为对象分配内存(在内存运行时数据区的堆区中为对象分配内存),并且初始化它的实例变量;对象生命周期结束Java虚拟机的垃圾回收线程回收对象的内存,一般只要Java程序中没有变量引用某个对象,该对象的生命周期结束,因此可以通过控制变量的生命周期来控制对象的生命周期。所谓的面向对象就是说:看到实体,对实体进行描述,创建实体对象,使用实体。2、匿名对象show(new Person());//匿名对象,可以作为实际参数进行传递。匿名对象另一个使用:当对对象的方法仅进行一次调用的时候,可以简化成匿名对象完成。3、封装通常将类中的成员变量私有化。对外提供方法对其进行访问。提供的目的是对成员数据进行控制,让其具备可控性。定义setXXX getXXX方法对成员变量进行访问。注意:私有仅仅是封装的表现形式之一。任何一种形式,只要隐藏细节,对外暴露访问方式,这些都称之为封装私有只能修饰成员。私有就是不能直接访问4、构造函数在对象创建时就被调用了。作用:对对象进行初始化。如果一个类中没有定义过构造函数。编译器在编译时,就给该类添加一个默认的构造函数。一旦在类中明确了自定义的构造时,该默认构造函数就没有了。当一个类中有多个构造函数时,它们是以重载形式体现的。类中的默认构造函数是带权限的,权限和类是一致的不同包中如果父类没有写任何权限是默认的话,子类也访问不到任何一个对象无论是数据还是行为,只要是一初始化存在的时候就具备的话,就把代码都定义在构造函数中构造函数和一般函数的区别?构造函数用于给对象初始化。初始化动作只执行一次。而一般函数可以被执行多次。5、 成员变量和局部变量的区别:1, 定义的位置。局部变量定义在函数中,语句内。成员变量定义在类中。2, 内存中的位置。局部变量存储在栈内存中。成员变量存储在堆内存中。3, 初始化值。局部变量没有默认初始化值,必须赋值才可以使用。成员变量有默认初始化值。4, 生命周期。局部变量一旦作用区域结束,就立刻释放。成员变量也称为实例(对象)变量,随着对象的出现而出现。随着对象的被回收而释放。6、this的使用this:代表的是对象。其实就一个对象的引用。它代表哪个对象呢?哪个对象调用了this所在的函数,this就代表哪个对象。this:代表的是本类型对象的的引用。static方法中不可以书写this。因为static先加载优先于对象。 this的使用之一:当成员变量和局部变量同名时,可以用this来区分。this的使用之二:使用this(参数列表)的方式就可以实现构造函数之间的调用。注意:构造函数之间调用时,this语句只能定义在构造函数的第一行。因为初始化动作必须先执行。当功能内部使用到了本类对象时,用this表示。所有对象成员要被使用,必须先有成员,所有成员要运行,前面必须跟对象,当对象不明确的时候,前面要加this.一般方法的运行都是通过对象.调用的形式来完成的[java] view plaincopyclass Student { //使用封装,将成员属性私有化 private String stuName; private int age; //get和set方法 //一般setXxxx()方法不需要返回值,但要带参数 void setStuName(String stuName){//局部变量覆盖成员变量 this.stuName = stuName;//这里的this是必须要显示使用 } String getStuName(){ return this.stuName; //这里的this不是必须的 } void setAge(int age){ this.age = age; } int getAge(){ return this.age; } //打印的方法 void printMe(){ System.out.println("大家好,我叫: " + this.stuName + " ,我今年:" + this.age + " 岁了!");//this也不是必须的 } } class Demo { public static void main(String[] args) { Student stu = new Student(); stu.setStuName("张学友"); stu.setAge(20); stu.printMe(); // System.out.println(stu.getStuName() + " ," + stu.getAge());//通过getXxx()方法获取 } } 1、继承的特点Java中只支持单继承。并不直接支持多继承。单继承:一个子类只能有一个父类。 多继承:一个子类可以有多个父类。不直接支持,对其进行改良。 继承层次多了,就形成了继承体系。体系就是不断向上抽取而来的。在使用一个体系的时候,先参阅最顶层类,了解体系的最基本功能。使用时,创建该体系最底层类的对象。看顶层,用底层。什么时候使用继承呢?当A类是属于B类中的一种时,就使用继承。2、继承的好处好处:1,提高了代码的复用性。 2,让类与类之间产生了关系,为多态特征提供了前提。子类可以直接访问父类中的非私有的成员,间接访问私有成员通过方法的形式。3、继承中子父类成员的特点1、成员变量super:代表的就是父类。super的用法和this很相似。用法 super.父类成员。 super(实际参数);this:代表的是本类型对象的引用。super:代表的是父类的内存空间。子父类中出现同名成员变量时用super区分出父类变量。但是这种情况很少出现。2、继承中成员函数的特点当子父类中出现一模一样的函数时。出现了另一个函数特性:覆盖,复写,重写。overload(重载):只关注本类中同名函数的参数列表。不关注返回值类型。override(覆盖):子父类中一模一样的函数,才会覆盖。保留父类功能声明,建立子类功能内容,这就是覆盖。 覆盖注意事项:1,子类覆盖父类方式,必须要保证子类方法权限大于等于父类方法权限。2,静态只能覆盖静态,或者被静态覆盖。覆盖就是沿袭了父类功能的声明,其实是创建了子类的内容而已,内容是子类的,声名是父类的。3、子父类中构造函数的特点:子类的实例化过程:子类的所有构造函数中的第一行都有一条默认的隐式语句 super();super():用来调用父类中的空参数的构造函数。子父类的成员对象都在子类对象的堆内存空间中子类对象一创建,父类的变量就会存在为什么子类中都要有默认super语句呢?因为子类对象中会存储父类中的属性数据,必须要对子类对象初始化时,先执行父类的初始化动作,看看父类是如何对自己的属性数据进行初始化的。为了给父类的变量进行初始化所以,子类的所有构造函数默认第一行(因为初始化动作要先执行,所以定义在第一行)都有一条默认的super()语句。 如果父类中没有定义空参数的构造函数,子类构造函数必须通过super语句或者this语句指定要访问的构造函数。类本身就是现实生活中对象共性内容的抽取4、final关键字:1,修饰符,修饰类,方法,各种变量。2,final修饰类不可以被继承。3,final修饰的方法不可以被覆盖。4,final修饰的变量是一个常量,只能赋值一次。对固定不变的值进行名称的定义 。提高其阅读性。final修饰的常量 命名规则 所有字母都大写。多个单词,单词间用_连接。5、抽象类类是用来描述事物,当没有足够的信息去描述一个事物时,这个描述就是抽象的。1、抽象类的特点:1,抽象方法只有声明,没有方法体。2,抽象方法一定定义在抽象类中,都需要被abstract关键字修饰。3,抽象类不可以用new创建对象。4,抽象类必须有自己的子类覆盖了所有的抽象方法后,该子类才可以被实例化。否则,该子类还是一个抽象类。2、抽象类一定是个父类?是,抽象类不具体,需要子类将其具体化,并实例化。3、抽象类中有构造函数吗?有。用来给子类进行对象初始化。抽象类和一般类有什么区别呢?相同点:都是用来描述事物的,内部都可以定义属性,行为,构造器。区别:抽象类中可以定义抽象方法。不可以实例化。因为不具体。 一般类中不可以定义抽象方法,可以实例化。4、抽象关键字不可以和哪些关键字共存?final,private,static,如果静态可以存在,这个成员就不需要对象了,可以用类名直接调用,但是方法没有主体,是没有意义的,5、抽象类中是否可以不定义抽象方法?可以的。这样做仅为不让该类实例化。6、接口如果一个抽象类的方法都是抽象的,这时可以将抽象类用另一种形式来体现。就是接口。 接口定义的关键字就是 interface 子类必须实现了接口中所有的抽象方法后,子类才可以实例化。否则,该子类是一个抽象类。1、接口中成员的定义:常见成员有两种:1,全局常量。2,抽象方法。接口中的成员都是public的。2、接口的好处是将多继承进行改良,用多实现进行体现。一个类只能继承一个类,但是一个类可以实现多个接口。另一个体现。一个类在继承另一个类的同时,还可以实现多接口。接口的出现避免了单继承的局限性。3、类与类之间存在继承是为什么呢?类当中有一些定义好的东西,另外一个类直接继承就能拿过来用,叫继承4、java改良多继承的原因?多继承不能存在的原因是调用的不确定性,多个父类出现了一模一样的功能,但是功能的内容却不一样。多实现解决了以上的问题,因为接口中的方法没有方法体,即使出现相同函数只需要在子类实现一次即可,就完成了所有父类方法的覆盖。5、先继承再多实现继承的是主体功能,接口都是扩展功能,基于主题功能需要的扩展功能。一个程序想具备扩展性必须使用接口6、java支持多继承吗?对于类多继承是用多实现的方式来体现的,在类上不能直接支持,会产生调用的不确定性。但是,接口之间支持多继承。接口的方法是没有主体的,所以多继承变成多实现,在接口上,多继承依然存在。7、接口的思想接口就是生活中的一种规则,降低了耦合性,提高了扩展性,实现了模块式的开发。接口是在降低耦合性,所以会有两方,一方在使用接口,一方在实现接口封装性:把实现细节封装,对外暴露规则[java] view plaincopy/* super和this的区别: 1.this始终是指向本类的成员: 1).访问本类的成员; class A{ int num = 10; void f1(){ System.out.println("num = " + this.num); this.f2();//调用本类的f2()方法 } void f2(){ } } 2).在本类的构造方法中,调用本类其它的构造方法; class A{ A(){ System.out.println("a1"); } A(int b){ this();//调用此类无参的构造方法;它必须是这个构造方法的第一条有效语句; System.out.println("a2"); } } main(){ A a = new A(2); } 2.super始终是指向父类的空间: 1.通过super可以访问父类的成员: (重点) 2.可以调用父类的构造方法; 3.在子类中的构造方法,默认情况下会在第一行自动添加一句:super();//调用父类的无参的构造方法; 4.注意: 如果父类没有无参的构造方法,那么子类的构造方法中,就必须使用super()去显示的去调用父类的某个 带参的构造方法; 5.在子类的构造方法中调用父类的构造方法使用super().这里也要求super()必须是这个构造方法的第一句话; 6.在子类的构造方法中,不能即使用this()又使用super();因为都需要在第一句话; 小结: 1.this可以访问本类成员属性和成员方法;调用本类其它构造方法 2.super可以访问父类的成员属性和成员方法;调用父类的构造方法; 3.有一个时候,需要我们在子类中必须显示的使用super()去调用父类的构造方法: 当父类没有无参构造方法时: class A{ A(int a){ } } class B extends A{ //不论子类中有多少个构造方法,每个构造方法内都要显示的去super(),调用父类带参构造方法; B(int n){ super(n); } } */ class A{ int num = 10; A(int b){ // this();//调用此类无参的构造方法;它必须是这个构造方法的第一条有效语句; System.out.println("a2"); } void fun(){ System.out.println("父类的fun()方法"); } } class B extends A { B(int n){ super(n);//调用了父类的带一个int参数的构造方法; // this("aaa"); } B(String a ){ } int num = 20; void show(){ System.out.println("num = " + super.num);//父类的num super.fun();//父类的fun()方法 } } class Demo { public static void main(String[] args) { // new B().show(); new B(20); } } 1、接口和抽象类的区别共性:抽象类和接口都是不断向上抽取而来的。区别:1,抽象类中可以定义抽象方法也可以定义非抽象方法,非抽象方法可以直接提供给子类使用。接口中只能定义抽象方法。2,类与类之间是继承关系,is a关系。 类与接口之间是实现关系。like a关系。 抽象类一般描述的都是一个体系is a,接口是给体系进行功能扩展like a3,类与类之间只能单继承。 类与接口之间可以多实现。2、多态多态:多种形态。多态在程序中的体现:父类或者接口的引用指向了自己的子类对象多态的前提:1,必须有继承或者实现的关系。2,通常都有覆盖的操作。多态的好处:提高了程序的扩展性,在思想上也有不同,以前是面对一个对象调用,对象多了调用麻烦。 相当于指挥一批对象做事情,将复杂事情简单化。多态的弊端:多态的出现,虽然可以让前期的程序使用后期的内容。 不可以使用子类的特有内容。向上转型Animal a = new Cat();//向上转型(类型提升)。子类对象提升为了父类型。提升的好处:就是提高了扩展性。隐藏了子类型。提升的局限性:只能使用父类中的方法。 如果子类有覆盖的话,运行的是子类的内容。向下转型Cat c = (Cat)a;//向下转型(强制类型转换)。好处:可以使用具体子类型的特有方法。向下转型需要注意:父类型向下转成子类型,因为子类型不唯一,所以,需要进行判断。如何判断对象类型呢? 用到一个关键字完成,instanceof 对象 instanceof 类or接口记住:一旦向下转型,必须先instanceof判断记住:对于子父类转型动作,自始自终都是子类对象在做着类型的转换而已。3、多态中成员的特点1,成员变量。多态调用时,对于成员变量,无论是编译还是运行,结果只参考引用型变量所属的类中的成员变量。参考等号左边。2,成员函数。多态调用时,对于成员函数,编译时,参考引用型变量所属的类中是否有被调用的方法。有,编译通过,没有编译失败。运行时,参考的是对象所属的类中是否有调用的方法。简单说:编译看左边,运行看右边。3,静态函数。简单说:编译和运行都看左边。4、API:Application Programming Interface应用程序接口java对外提供的,对外暴露的公共的部分都称之为接口[java] view plaincopy/* 孔子装爹的案例: class 孔爹{ int age = 85; void teach(){//讲 System.out.println("讲Java"); } } class 孔子 extends 孔爹{ int age = 60; void teach(){ System.out.println("讲IOS"); } void playGame(){ System.out.println("斗地主"); } } //假如有一天,一个人请"孔爹"讲Java,"孔爹"去讲课了。 //之后,又来一个人请"孔爹"讲Java,此时"孔爹"没在家,"孔子"在,来人说给的价格还很高,"孔子"觉得 //有钱赚,自己进屋化妆,穿上"孔爹"的衣服,贴上胡子,就冒充"孔爹"去了 main(){ 孔爹 kd = new 孔子(); //讲课 kd.teach();//孔子只会讲IOS,所以这里讲解的是IOS //课间自己想打会游戏 // kd.playGame();//编译失败,不能访问子类自有的成员 //讲完课之后,装了一天"孔爹"的"孔子",回家脱下衣服,摘下胡子,又还原为"孔子" 孔子 kz = (孔子)kd; kz.playGame();//这时可以打游戏了 } */ class 孔爹{ int age = 85; void teach(){//讲 System.out.println("讲Java"); } } class 孔子 extends 孔爹{ int age = 60; void teach(){ System.out.println("讲IOS"); } void playGame(){ System.out.println("斗地主"); } } class Demo { public static void main(String[] args) { 孔爹 kd = new 孔子(); //讲课 kd.teach();//孔子只会讲IOS,所以这里讲解的是IOS //课间自己想打会游戏 // kd.playGame();//编译失败,不能访问子类自有的成员 //讲完课之后,装了一天"孔爹"的"孔子",回家脱下衣服,摘下胡子,又还原为"孔子" 孔子 kz = (孔子)kd; kz.playGame();//这时可以打游戏了 } }
0 0