黑马程序员——Java面向对象-整理笔记
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
一、面向对象思想
面向对象的基本思想是,从现实世界中客观存在的事物出发来构造软件系统,并在系统的构造中尽可能运用人类的自然思维方式。
面向对象更加强调运用人类在日常生活的逻辑思维中经常采用的思想方法与原则,如抽象、分类,继承、聚合、多态等。
人在思考的时候,首先眼睛里看到的是一个一个的对象。
面向对象的三大特征:封装、继承和多态。
1.封装:
继承是面向对象的一个重要特征。当多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继那个类即可。这时,多个类可以称为子类,单独的这个类称为父类或者超类。
封装的优点:
①提高了代码的复用性。
②让类与类之间产生了关系。这个关系,提供了多态的前提。
注:Java语言中,只支持单继承,不支持多继承。例:一个儿子只能有一个父亲。
封装的弊端:
类的耦合性增强了。而开发的原则是高内聚,低耦合。
2.继承:
继承的特点:
①Java只支持单继承,不支持多继承。(一个儿子只能有一个爹)
②Java支持多层继承(继承体系)
③如果想用这个体系的所有功能用最底层的类创建对象
④如果想看这个体系的共性功能,看最顶层的类
使用继承的注意事项:
①子类只能继承父类所有非私有的成员(成员方法和成员变量)
②子类不能继承父类的构造方法,但是可以通过super()(super()一定要放在构造方法的开头)关键字去访问父类构造方法,用super.方法/super.成员变量----可以调用父类 的成员方法。在实例化子类的对象时,会自动调用父类的无参构造方法,有参数的构造方法只能用super调用。
③重写父类的方法时,修饰方法的修饰权限只能从小范围到大范围改变
④重写方法还可以修改方法的返回值类型,但是重写的返回值类型必须为父类中同一方法返回值类型的子类
⑤现有父类Father,子类Son。
Father f=new Son(); //向上转型(f会调用子类中重新的父类的方法)
Son s=f; //这句话不正确,父类对象不能隐式转换为子类对象
Son ss=(Son)f; //向下显示转换,及强制转换
可以使用instanceof关键字来判断父类引用是否为子类对象的实例
if(f instanceof Son)
Son ss=(Son)f;
⑥在自定义的类中使用equal()方法时将返回false,因为Object类中的equal()方法默认使用“==”来比较,而“==”比较的是两个对象的引用地址,而不是对象的内容。所以在自定义类中要重写equal()方法(String就是重写了equal方法,所以String类型可以直接使用“==”来比较两个字符串的大小)
3.多态:
子类继承父类后,同一个方法有不同的表现体现在两个方面:方法重载实现的静态多态性(编译时多态),方法重写实现的动态多态性(运行时多态)。
重写方法的调用原则:子类重写父类的方法,调用子类方法;反之,调用父类的方法
多态的前提:子类重类与类之间必须有关系,要么继承,要么实现。
存在覆盖。父类中有方法被子类重写写父类的方法,调用子类方法;反之,调用父类的方法。
多态的利与弊 :
利:提高了程序的可扩展性和后期可以维护性。
弊:只能使用父类中的引用访问父类中的成员。也就是说使用了多态,父类型的引用在使用功能时,不能直接调用子类中的特有方法。如果此时父类的引用想要调用子类 中特有的方法,就需要强制将父类的引用,转成子类类型,向下转型。如:Catc = (Cat)a;
注:如果父类可以创建对象,就不可以把此夫类对象强制转换成子类引用。所以千万不能出现这样的操作,就是将父类对象转成子类类型。
我们能转换的是父类引用指向了自己的子类对象时,该引用可以被提升,也可以被强制转换。多态至始至终都是子类对象在做着变化。
多态的特点
①多态中非静态成员函数的特点
在编译时期:参阅引用型变量所属的类中是否有调用的方法。如果有,编译通过,如果没有编译失败。
如果父类中有一个非抽象的方法,而子类继承后又将其复写了,在多态运行时,父类的引用调用这个同名函数时,被运行的将是父类中的方法。
简单总结就是:成员函数在多态调用时,编译看左边,运行看右边。
②多态中成员变量的特点
无论编译和运行,都参考左边(引用变量所属的类)。如:父类引用调用成员变量时,如果父类和子类有同名的成员变量,那么被调用的是父类中的成员变量。
③多态中静态成员函数的特点
无论编译和运行,都参考左边。也就是父类引用在调用静态同名函数时,被调用的是父类中的静态函数。这是因为,当类一被加载,静态函数就随类绑定在了内存 中。此时,不需要创建对象,就可以使用类名直接调用。同时,父类中的静态成员函数一般是不被复写的。
示例代码:
<span style="font-size:12px;">public class MyTest { public static void main(String[] args) { Father tt = new Son(); //调用父类中的成员变量 System.out.println(tt.a); //调用子类中的重写方法 tt.callMe(); //调用父类中的静态方法 tt.myStatic(); } } class Father{ public String a="父类成员变量"; public void callMe(){ System.out.println("父类方法:callMe()"); } public static void myStatic(){ System.out.println("父类静态方法:myStatic()"); } } class Son extends Father{ //子类重写父类的成员变量和方法 public String a="子类成员变量"; public void callMe(){ System.out.println("子类方法callMe()"); } public static void myStatic(){ System.out.println("子类静态方法:myStatic()"); } }</span>运行结果:
父类成员变量
子类方法callMe()
父类静态方法:myStatic()
二、类与对象
类与对象的关系
类是描述具有相同特征的一类事物的基本原型,定义了这类事物所拥有的数据特征以及可以执行的操作;对象是类的实例,是类的具体化。
java类是面向对象封装概念的基本体现,java类封装了抽象概念的数据(属性)与行为(方法)。
java类的基本构成:属性、方法、构造方法
属性是是类对抽象概念数据特征的描述,方法是类对概念行为的描述,构造方法在类的对象实例化时对类对象进行初始化。成员变量不设置初始值时,会有默认值)。
重载与覆写(重写)
重载:方法的重载是多态性的体现,重载方法具有相同的方法名称,但方法参数列表不同(参数类型或数目不同),重载为相似功能提供了不同的实现
重写:重写是指在子类中覆盖父类方法的实现,对父类方法进行重新定义,当父类引用指向子类对象并调用重写方法时,将调用子类方法的实现。子类函数的访问修饰权限不能低 于父类的。
super与this
super代表当前类的父类(超类),子类的构造函数如果要引用super的话,必须把super放在函数的首位;当子类变量与父类变量重名时,使用super调用父类变量。
this代表当前对象,this使用:this.属性,this.方法,this();使用this来区别重名的局部变量与成员变量;使用this在一个构造函数中调用其他的重载构造函数。
类的访问权限修饰符:
类的权限设定会约束类成员变量或方法上的权限设定
构造方法:
每个类都有构造方法。如果没有显式地为类定义构造方法,Java编译器将会为该类提供一个默认构造方法。
若类中定义了有参数的构造方法,那么编译器就不会再为类设置一个无参的构造方法了。
无参的构造方法可以使用this(参数)来调用有参的构造方法。
static修饰符:
①修饰成员变量:该变量为静态变量(类变量),属于类本身,所有该类对象公用该变量。
②修饰方法:该方法为静态方法,在静态方法中不能使用非静态成员变量或方法,因为在静态方法调用时可能还没有对象被创建,没有对象也就无法获取其成员。静 态成员函数中也不能使用this或者super,因为它们是和类的对象相关联的。
③静态内部类:静态内部类可以对照静态成员变量来理解。
④可以使用类名.静态成员来调用静态成员变量。
⑤在Java中规定,不能讲方法体中的局部变量声明为static。
⑥如果在执行类时,希望先执行类的初始化动作,那么可用static定义一个静态区域,例如
public class Test{
static {代码}
}
final修饰符:
①final修饰成员变量:该变量为常量;修饰方法:该方法不能够在子类中被重写;修饰类:该类不能被继承。
②可以改变指定为final的引用中的成员变量的值,但不能改变final修饰的引用指向其他引用。
③定义为private的方法隐式被指定为final类型。
④final类中的方法被隐式设置为final,但成员变量可为final和非final。
abstract修饰符:
①定义抽象类、方法。
②抽象方法 没有方法体,仅有方法声明。
③抽象类中可以没有抽象方法,有抽象方法的类一定是抽象类。
④抽象类被继承后需要实现其中的所有的抽象方法,抽象类中可以有非抽象方法。
interface修饰符:
①接口用关键字interface表示:interface 接口名 {},接口中都没有方法体,接口是一种特殊的抽象类。
②类实现接口用implements表示:class 类名 implements 接口名 {}
③接口成员特点:成员变量:只能是常量,并且是静态的;
默认修饰符:public static final;
构造方法:接口没有构造方法;
成员方法:只能是抽象方法;
默认修饰符:public abstract;
内部类与外部类:
内部类的访问规则:
①内部类可以直接访问外部类中的成员,包括私有。之所以可以直接访问外部类中的成员,是内部类中持有了一个外部类的引用。格式:外部类名.this
②外部类要访问该内部类,必须建立内部类对象;
访问格式:
①当内部类定义在外部类的成员变量位置上,而且非私有,可以再外部其他类中直接建立内部类对象。
格式:外部类名.内部类名 变量名 = 外部类对象.内部类对象;
Outer.Inner in = new Outer().new Inner();
②当内部类在成员位置上,就可以被成员修饰符所修饰。
比如,private:将内部类在外部类中进行封装。
static:内部类就具备了静态的特性。
③内部类被static修饰后,只能直接访问外部类中的static成员,出现了访问局限。
④ 在外部其他类中,访问static内部类的非静态成员
new Outer.Inner().function();
⑤在外部其他类中,访问static内部类的静态成员
outer.Inner().function();
注意:当内部类中定义了静态成员,该内部类必须是静态的。当外部类中的静态为方法访问内部类时,内部类也必须是静态的。
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------