黑马程序员——Java中的面向对象
2015-09-05 19:46
447 查看
——- android培训、java培训、期待与您交流! ———-
面向过程,强调的是功能行为;面向对象,将功能封装进对象,强调具备了功能的对象。
私有仅仅是封装的一种表现形式,提供对外访问方式(set和get方法)可以对数据进行操作判断,提高安全性
包也是一种封装形式
包与包之间的类进行访问,被访问的包中的类必须是public的,被访问的包中的类的方法也必须是public的。
继承(Inheritance):类之间共享属性和操作的机制(子类继承父类,直接获得父类的属性和方法,实现类复用);通过extends关键字让类与类之间产生继承关系
特点:
子类可以直接访问父类中的非私有的属性和行为,子类无法继承父类中私有的内容(方法和变量)
提高了代码的复用性
Java只支持单继承,不支持多继承,但支持多层继承
继承代码示例:
运行结果:
多态(Polymorphism):子类对象直接赋给父类变量,运行时依然表现子类特征。
定义:某一类事物的多种存在形态。
作用:多态的存在提高了程序的扩展性和后期可维护性(弊端:前期定义的内容不能调用后期子类的特有内容)
多态时,成员的特点:
成员函数(非静态):示例中为method1()、method2()和method3()。
在编译时期:参考引用型变量所属的类中是否有调用的函数(有,编译通过(method1()被复写,method2()为父类);没有,编译失败(如method3()父类中不存在))。
在运行时期:参考的是对象所属的类中是否有调用的函数
简单说:编译看左边,运行看右边。
静态成员函数:实例中的method4()。
继承中,父类为static的方法无法被覆盖
编译时:参考的是对象所属的类中是否有调用的函数
运行时:参考的是对象所属的类中是否有调用的函数
简单说:编译和运行看左边。
成员变量(静态和非静态):非静态的str1与静态的str2。
在编译时:参考引用型变量所属的类中是否有调用的成员变量(有,编译通过,没有,编译失败)。
在运行时:参考引用型变量所属的类中是否有调用的成员变量,并运行该所属类中的成员变量。
简单说:编译和运行都参考等号的左边。
代码示例:
以下为运行结果:
开发和设计过程
开发过程:不断创建对象、使用对象和指挥对象做事
设计过程:管理和维护对象之间的关系
[b]内部类:[/b]
将一个类定义在另一个类的里面,里面那个类就称为内部类(内置类,嵌套类)。
特点:
内部类可以直接访问外部类中的成员,包括私有成员。
而外部类要访问内部类中的成员必须要建立内部类的对象。
定义时机:分析事物时,发现该事物描述中还有事物,而且这个事物还在访问被描述事物的内容,这时候就定义内部类。
访问格式:
当内部类定义在外部类的成员位置上,而且非私有,可以在外部其他类中直接建立内部类对象
格式:
外部类名.内部类名 变量名=外部类对象.内部类对象;
e.g.: Outer.Inner in=new Outer().new Inner();
当内部类在成员位置上,就可以被成员修饰符所修饰。比如:private:将内部类在外部类中进行封装当内部类被static修饰后,只能访问外部类中的static成员。出现了访问局限
在外部其他类中,内部类为静态,直接访问static内部类的非静态成员
格式:new Outer.Inner().function();
在外部其他类中,内部类为静态,直接访问static内部类的静态成员:可以不用创建内部类对象,直接调用
格式:Outer.Inner.function();
内部类能直接访问外部类中的成员的原因:因为内部类持有了外部类的引用,外部类名.this
注意:
当内部类中定义了静态成员,该内部类必须是static的
当外部类中的静态方法访问内部类时,内部类也必须是static的。
内部类定义在局部位置上,也可以直接访问外部类中的成员。同时可以访问所在局部中的局部变量,但必须是被final修饰的。
[b]匿名内部类:[/b]
定义:内部类的简化写法
前提:内部类可以继承或实现一个外部类或者接口
格式:
[b]抽象类:[/b]
定义:Java中定义只有功能声明,没有方法体的方法,该方法的具体实现由子类完成,该方法称为抽象方法,包含抽象方法的类就是抽象类。
格式:
特点:
- 抽象类和抽象方法必须用abstract关键字来修饰
- 抽象类不可以被实例化,也就是不可以用new创建对象
- 抽象类需通过其子类实例化,而子类需要覆盖掉抽象类中所有的抽象方法后才可以创建对象,因此抽象类一定是父类
- 抽象类中可以定义抽象方法和非抽象方法,子类继承后,可以直接使用非抽象方法
[b]接口:[/b]
概念:当一个抽象类中的方法都是抽象的时候,这时可以将该抽象类用另一种形式定义和表示,就是接口。
格式:
接口中的成员修饰符是固定的:
1. 成员常量:public static final
2. 成员函数:
特点:
接口中的成员都是公共的权限
接口是对外暴露的规则,接口是程序的功能扩展
接口的出现将“多继承”通过另一种形式体现出来,即“多实现”
一个类在继承另一个类的同时,还可以实现多个接口。
类与类之间是继承关系,类与接口直接是实现关系,可以多实现
接口与接口之间是继承关系,而且接口可以多继承
接口中只能定义抽象方法,必须由子类去实现
成员变量和局部变量区别:
成员变量(2种):实例Field(不以static修饰)和类Field(以static修饰):
范围:定义在类中,在整个类中都可以被访问。
存储:实例Field**堆内存**(随对象的建立而建立,随对象对象被回收而释放);
类Field(静态变量)存储在方法区(共享数据区)的静态区,随着类的加载而存在,随着类的消失而消失。
默认初始化值:有。
局部变量(3种):形参(方法签名中定义的变量)、方法局部变量(在方法内定义)和代码块局部变量(在代码块定义)
范围:只定义在局部范围内(3处)只在所属的区域有效。
存储:栈内存中(作用的范围结束,变量空间会自动释放)。
默认初始化值:无。
对象的产生:创建对象的根本途径是构造器(特殊的方法),通过new关键字来调用某个类的构造器即可创建这个类的实例。
[b]匿名对象:[/b]
对象的简化形式(一个没有名字的对象, 创建了一个对象出来,没有赋给一个变量);使用情形:当对对象方法仅一次调用时;作为实际参数进行传递时。
基本数据类型参数及引用数据类型参数传递比较示例:
一个用于创建实例时,执行初始化的特殊方法。
构造器是一个类创建对象的根本途径,系统默认为类提供一个空参的构造器(其执行体为空),当创建一个对象时,系统默认初始化,将基本类型的Field设为0(数值型)或false(布尔型),引用类型的Feild设为null;若想改变这种默认初始化,即可使用构造器来实现。
一旦自定义构造器后,系统将不会提供默认的构造器(一般建议为该类额外编写一个无参的做保留)。
[b]特点:[/b]
函数名与类名相同
不用定义返回值类型(在构造函数前面加上返回值就只是一般函数了)
没有具体的返回值
多个构造函数是以重载的形式存在的
继承中,子类构造函数执行时,父类构造函数也运行了(原因:在子类的构造函数中,第一行有一个默认的隐式语句:super())
[b]作用:[/b]
给对象进行初始化。
定义时机:
分析事物,该事物具备一些特性或者行为,就把把这些内容定义到构造函数中,若需要参数进行运算就定义参数。
[b]作用:[/b]
给对象初始化,定义的是不同对象共性的初始化内容对象一建立就运行,而且优先于构造函数执行。
[b]与构造函数区别:[/b]
构造代码块是给所有对象进行统一初始化,而构造函数是给对应的对象初始化。
[b]代码示例:[/b]
运行结果:
一,面向对象简介
1. 面向对象概念
面向对象是相对面向过程而言,面向对象和面向过程都是一种思想。面向过程,强调的是功能行为;面向对象,将功能封装进对象,强调具备了功能的对象。
2. 基本特征(3个):
封装(Encapsulation):将对象实现细节隐藏,通过一些共用方法来暴露对象的功能;提高类的内聚性,降低了对象之间的耦合性;私有仅仅是封装的一种表现形式,提供对外访问方式(set和get方法)可以对数据进行操作判断,提高安全性
包也是一种封装形式
包与包之间的类进行访问,被访问的包中的类必须是public的,被访问的包中的类的方法也必须是public的。
继承(Inheritance):类之间共享属性和操作的机制(子类继承父类,直接获得父类的属性和方法,实现类复用);通过extends关键字让类与类之间产生继承关系
特点:
子类可以直接访问父类中的非私有的属性和行为,子类无法继承父类中私有的内容(方法和变量)
提高了代码的复用性
Java只支持单继承,不支持多继承,但支持多层继承
继承代码示例:
class Fu { Fu() { super(); show();// 该方法被子类复写,调用的是子类的show方法,此时其成员变量num还未进行显示初始化 } void show() { System.out.println("fu show"); } } class Zi extends Fu { int num = 8; Zi() { super();// 通过super初始化父类内容时,子类的成员变量并未显示初始化,等super()父类初始化完毕后,才进行子类的成员变量显示初始化 } void show() { System.out.println("zi show..." + num); } } class ExtendsDemo { public static void main(String[] args) { Zi z = new Zi(); z.show(); } }
运行结果:
多态(Polymorphism):子类对象直接赋给父类变量,运行时依然表现子类特征。
定义:某一类事物的多种存在形态。
作用:多态的存在提高了程序的扩展性和后期可维护性(弊端:前期定义的内容不能调用后期子类的特有内容)
多态时,成员的特点:
成员函数(非静态):示例中为method1()、method2()和method3()。
在编译时期:参考引用型变量所属的类中是否有调用的函数(有,编译通过(method1()被复写,method2()为父类);没有,编译失败(如method3()父类中不存在))。
在运行时期:参考的是对象所属的类中是否有调用的函数
简单说:编译看左边,运行看右边。
静态成员函数:实例中的method4()。
继承中,父类为static的方法无法被覆盖
编译时:参考的是对象所属的类中是否有调用的函数
运行时:参考的是对象所属的类中是否有调用的函数
简单说:编译和运行看左边。
成员变量(静态和非静态):非静态的str1与静态的str2。
在编译时:参考引用型变量所属的类中是否有调用的成员变量(有,编译通过,没有,编译失败)。
在运行时:参考引用型变量所属的类中是否有调用的成员变量,并运行该所属类中的成员变量。
简单说:编译和运行都参考等号的左边。
代码示例:
/* 多态中成员(函数和变量)调用特点示例: */ class BaseClass { String str1 = "父类非静态成员变量"; static String str2 = "父类静态成员变量"; void method1() { System.out.println("base method_1"); } void method2() { System.out.println("base method_2"); } static void method4() { System.out.println("static base method_4"); } } class SubClass extends BaseClass { String str1 = "子类非静态成员变量"; static String str2 = "子类静态成员变量"; //复写父类的method1()方法 void method1() { System.out.println("sub method_1"); } void method3() { System.out.println("sub method_3"); } static void method4() { System.out.println("static sub method_4"); } } class PolymorphismDemo { public static void main(String[] args) { System.out.println("多态中非静态成员函数调用示例:"); BaseClass bs = new SubClass(); bs.method1(); //sub method_1 bs.method2(); //base method_2 // f.method3(); //编译不能通过,因父类没有method3()函数 System.out.println("----------------------- "); System.out.println("多态中静态成员函数调用示例:父类"); bs.method4(); //static base method_4 System.out.println("--------------------------"); System.out.println("多态中成员变量调用示例:均为父类"); System.out.println(bs.str1); //父类非静态成员变量 System.out.println(bs.str2); //父类静态成员变量 } }
以下为运行结果:
开发和设计过程
开发过程:不断创建对象、使用对象和指挥对象做事
设计过程:管理和维护对象之间的关系
二,类与对象
1. 类:
具有共同属性(成员变量)、共同方法(成员函数)的一类事物[b]内部类:[/b]
将一个类定义在另一个类的里面,里面那个类就称为内部类(内置类,嵌套类)。
特点:
内部类可以直接访问外部类中的成员,包括私有成员。
而外部类要访问内部类中的成员必须要建立内部类的对象。
定义时机:分析事物时,发现该事物描述中还有事物,而且这个事物还在访问被描述事物的内容,这时候就定义内部类。
访问格式:
当内部类定义在外部类的成员位置上,而且非私有,可以在外部其他类中直接建立内部类对象
格式:
外部类名.内部类名 变量名=外部类对象.内部类对象;
e.g.: Outer.Inner in=new Outer().new Inner();
当内部类在成员位置上,就可以被成员修饰符所修饰。比如:private:将内部类在外部类中进行封装当内部类被static修饰后,只能访问外部类中的static成员。出现了访问局限
在外部其他类中,内部类为静态,直接访问static内部类的非静态成员
格式:new Outer.Inner().function();
在外部其他类中,内部类为静态,直接访问static内部类的静态成员:可以不用创建内部类对象,直接调用
格式:Outer.Inner.function();
内部类能直接访问外部类中的成员的原因:因为内部类持有了外部类的引用,外部类名.this
注意:
当内部类中定义了静态成员,该内部类必须是static的
当外部类中的静态方法访问内部类时,内部类也必须是static的。
内部类定义在局部位置上,也可以直接访问外部类中的成员。同时可以访问所在局部中的局部变量,但必须是被final修饰的。
[b]匿名内部类:[/b]
定义:内部类的简化写法
前提:内部类可以继承或实现一个外部类或者接口
格式:
new 父类构造器([实参列表]) 或 接口() { //匿名内部类的类体部分 }
[b]抽象类:[/b]
定义:Java中定义只有功能声明,没有方法体的方法,该方法的具体实现由子类完成,该方法称为抽象方法,包含抽象方法的类就是抽象类。
格式:
修饰符 abstract 返回值类型 函数名(参数列表);
特点:
- 抽象类和抽象方法必须用abstract关键字来修饰
- 抽象类不可以被实例化,也就是不可以用new创建对象
- 抽象类需通过其子类实例化,而子类需要覆盖掉抽象类中所有的抽象方法后才可以创建对象,因此抽象类一定是父类
- 抽象类中可以定义抽象方法和非抽象方法,子类继承后,可以直接使用非抽象方法
[b]接口:[/b]
概念:当一个抽象类中的方法都是抽象的时候,这时可以将该抽象类用另一种形式定义和表示,就是接口。
格式:
interface{}
接口中的成员修饰符是固定的:
1. 成员常量:public static final
2. 成员函数:
public abstract 返回值类型 函数名(参数列表);
特点:
接口中的成员都是公共的权限
接口是对外暴露的规则,接口是程序的功能扩展
接口的出现将“多继承”通过另一种形式体现出来,即“多实现”
一个类在继承另一个类的同时,还可以实现多个接口。
类与类之间是继承关系,类与接口直接是实现关系,可以多实现
接口与接口之间是继承关系,而且接口可以多继承
接口中只能定义抽象方法,必须由子类去实现
成员变量和局部变量区别:
成员变量(2种):实例Field(不以static修饰)和类Field(以static修饰):
范围:定义在类中,在整个类中都可以被访问。
存储:实例Field**堆内存**(随对象的建立而建立,随对象对象被回收而释放);
类Field(静态变量)存储在方法区(共享数据区)的静态区,随着类的加载而存在,随着类的消失而消失。
默认初始化值:有。
局部变量(3种):形参(方法签名中定义的变量)、方法局部变量(在方法内定义)和代码块局部变量(在代码块定义)
范围:只定义在局部范围内(3处)只在所属的区域有效。
存储:栈内存中(作用的范围结束,变量空间会自动释放)。
默认初始化值:无。
2. 对象:
类的具体存在,该类事物实实在在存在的个体。对象的产生:创建对象的根本途径是构造器(特殊的方法),通过new关键字来调用某个类的构造器即可创建这个类的实例。
[b]匿名对象:[/b]
对象的简化形式(一个没有名字的对象, 创建了一个对象出来,没有赋给一个变量);使用情形:当对对象方法仅一次调用时;作为实际参数进行传递时。
基本数据类型参数及引用数据类型参数传递比较示例:
//基本数据类型参数传递 class Demo { public static void main(String[] args){ int x = 3; //方法局部变量 show(x); /*输出结果为3,因为show()方法中的x为方法局部变量,当主函数调用结束后,show方法出栈。 show方法参数x也随之出栈。main方法打印x的值。此时x指的是main方法中的x变量的值。 */ System.out.println("x=" + x); } public static void show(int x){ x = 4; //方法局部变量 } }
//引用数据类型参数传递 class Demo { int x = 3; //实例Feild,整个类中都可以访问。 public static void main(String[] args){ Demo d = new Demo(); d.x = 9; show(d); //show方法的参数d和main方法中的变量d同时指向了堆内存中同一个实体对象,堆内存中的实体对象的x属性值变为4。 /*show方法出栈,show方法参数d也随之出栈,main方法的变量d依然引用着堆内存中的实体对象, 因此堆内存中的实体对象不会被垃圾回收器清除。 */ System.out.println(d.x);//输出结果为4 } public static void show(Demo d){ d.x = 4; } }
2. 两者关系
类是对象的抽象,对象是类的实例。三,构造器和初始化块
1. 构造器(构造函数)
[b]简介:[/b]一个用于创建实例时,执行初始化的特殊方法。
构造器是一个类创建对象的根本途径,系统默认为类提供一个空参的构造器(其执行体为空),当创建一个对象时,系统默认初始化,将基本类型的Field设为0(数值型)或false(布尔型),引用类型的Feild设为null;若想改变这种默认初始化,即可使用构造器来实现。
一旦自定义构造器后,系统将不会提供默认的构造器(一般建议为该类额外编写一个无参的做保留)。
[b]特点:[/b]
函数名与类名相同
不用定义返回值类型(在构造函数前面加上返回值就只是一般函数了)
没有具体的返回值
多个构造函数是以重载的形式存在的
继承中,子类构造函数执行时,父类构造函数也运行了(原因:在子类的构造函数中,第一行有一个默认的隐式语句:super())
[b]作用:[/b]
给对象进行初始化。
定义时机:
分析事物,该事物具备一些特性或者行为,就把把这些内容定义到构造函数中,若需要参数进行运算就定义参数。
2. 初始化块(构造代码块)
关于局部代码块:局部代码块可以定义局部变量的生命周期class IfDemo{ public static void main(String[] args){ { int m = 89; System.out.println("Hello World..." + m); } /* *变量m是局部变量,生命周期仅在局部代码块括号中,当代码执行到局部代码块右括号外,变量m便消失了。 *局部代码块外的代码当然也就访问不到变量m了。 */ //System.out.println("over..." + m); } }
[b]作用:[/b]
给对象初始化,定义的是不同对象共性的初始化内容对象一建立就运行,而且优先于构造函数执行。
[b]与构造函数区别:[/b]
构造代码块是给所有对象进行统一初始化,而构造函数是给对应的对象初始化。
[b]代码示例:[/b]
class Person { private String name; private int age; //构造代码块,可以给所有对象进行初始化; { System.out.println("Running!"); } Person() { System.out.println("nane="+name+"...age="+age); } Person(String name) { this.name=name;//this 代表它所在函数所属对象的引用:哪个对象在调用this所在函数,this就代表哪个对象,该处为作用一 System.out.println("nane="+name+"...age="+age); } Person(String name,int a) { //this.name=name; //该句将少打印"name:null...age:0" this(name); //this(name),this语句用于构造函数之间的调用,将打印"name:null...age:0",this语句只能定义在构造函数的第一行,因为初始化要先执行,该处为作用二 age=a; System.out.println("nane="+name+"...age="+age); } public void setAge(int a) { if(a>0 && a<130) age =a; else System.out.println("age非法!"); } public int getAge() { return age; } public boolean campare(Person p) { return this.age==p.age;//函数内部要用到调用该函数的对象时,这时用this来表示这个对象,该处为作用一 } } class PersonDemo2 { public static void main(String[] args) { Person p1=new Person(); Person p2=new Person("小明"); p2.setAge(25); System.out.println(p2.getAge()); Person p3=new Person("小亮",26); Person p4=new Person("小贤",24); System.out.println(p4.campare(p3)); } }
运行结果:
相关文章推荐
- 黑马程序员之Collection类
- 黑马程序员之Map集合以及Collections静态方法
- BAT面试
- 临睡前的十分钟,决定未来职场的高度
- 程序员的十个层次
- 说我装13?过来,打屎你!(揭秘程序员装13面具)
- 程序员有趣的面试智力题
- 黑马程序员-Java基础:常用API
- 腾讯面试(三)
- 【年度总结】一个程序员的自我修养
- 黑马程序员--IO流(操作对象、管道流、RandomAccessFile)
- [翻译]程序员需要掌握的6项相关技能
- 黑马程序员——面向对象(多态+接口实现)-第18天
- 黑马程序员—Java基础:初识Java
- 黑马程序员----oc基础笔记----多态
- 运行时和常见面试题目
- 面试题28:字符串的排列
- 百度面试
- 面试题 10
- iOS求职之OC面试题