您的位置:首页 > 职场人生

黑马程序员_面向对象(1) 多态&继承&封装&关键字

2013-03-12 17:21 225 查看
-------android培训java培训、期待与您交流!
----------

一.面向对象概述

何谓面向对象:
所有的东西都是对象。

  程序是一大堆对象的集合,他们通过消息传递,各个对象之间知道要做些什么。

  每个对象都分配有自己的存储空间,可容纳其他对象。

  每个对象都有一个类型。

  同一类的所有对象能接收相同的消息

对象特征:
ehavior—说明这个对象能做什么。

   State—当对象施加方法时对象的反映。

   Identity---与其他相似行为对象的区分标志,每一个对象有唯一的indentity, 而这3者是相互影响的。

最重要的思想就是类,类是模板是蓝图,从类中构造一个对象,即创建了一个类的实例,打个比方:类好比一个建材市场,其中许多子类--各种各样的装饰材
料,而我们自己装饰的房子就是自己选择需要的材料
类之间的关系: 依赖关系(use - a),聚合关系(has -
a),继承关系(is - a)
OOP 设计最重要经验:谁拥有数据,谁就对外操作这些数据的方法
面试题:两块石头磨成一把石刀,石刀可以砍树,砍成木材,木材做成椅子。
木材做成椅子,木材是原材料,工厂设计
chair = ChairFactory.makeChar(wood);
木材是由石刀砍树得来了
wood = StoneKnife.cut(free)


石刀又是有两块石头磨成而来了,石头是原材料,工厂设计
stoneKnife = KnifeFactory.makeKnife(stone);

面向对象特征:
封装:隐藏对象的属性和实现的细节,只提供公共访问的方式。比如电脑里面的配件普通人不需要知道里面是怎样连接的,只需要知道外面的接口怎样使用有什么功能即可!这样的好处就是提高了复用性,安全性,还可以将变化隔离在那一部分代码,方便使用
eg:
public void print(Object obj){
System.out.println(obj);
}


继承:
多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只需要继承那个类即可

多态:一个对象在程序不同运行时刻代表的多种状态,父类或接口的引用指向子类

成员变量与局部变量
作用域:成员变量用于整个类
局部变量用于方法和语句中
生命周期:成员变量随着类的创建,存在堆区,随着类的消失而消失
局部变量 随着方法调用或者语句执行而存放在栈内存,调用后或语句结束自动释放
初始值: 成员变量有默认值
局部变量必须赋值
eg:
class  Test{
int a; // 成员变量
public void methA(){
int b = 0; // 局部变量
}
}


匿名对象: 没有名字的对象,调用一次,被gc自动释放回收
eg:
new Random().nextInt(100);

构造方法
特点: 方法名与类名相同,无返回值,无返回值类型
作用: 构造函数是用于创建对象并对其进行初始化赋值,对象一旦创建就会调用相应的构造函数
注意:没有定义构造方法,系统默认缺省的无参构造方法
eg:
public class Test{
Test(){ //无参构造

}
Test(int a,int b){ // 有参构造
}
}


构造函数没有覆盖。

构造函数没有继承过来,通过super访问父类构造函数。

在子类的构造函数中第一行有一个默认的隐式语句。super();

子类实例化过程,子类中所有的构造函数默认都会访问父类中的空参数的构造函数

eg:

class Fu
{
private int num = 4;
public void setNum(int num)
{
this.num =num;
}
public int getNum()
{
return this.num;
}
}

class Zi extends Fu
{
//int num = 5;
void show()
{
System.out.println(num);
}
}

class  ExtendsDemo2
{
public static void main(String[] args)
{
Zi z = new Zi();
z.show();
//System.out.println(z.num+"...."+z.num);
}
}


对象在JVM初始化过程
/**一个对象实例化过程:
Person p = new Person();
1.jvm读取并解释的Person.class文件,进行解析,并加载进内存,进入到方法区,形成常量池与方法表
2.并会先加载Person的父类(如果有直接的父类的情况下).在堆内存中开辟空间,分配地址。
3.并在对象空间中,对对象中的属性进行默认初始化。
4.调用对应的构造函数进行初始化。
5.在构造函数中,第一行会先调用父类中的构造函数进行初始化。
6.父类初始化完毕后,再对子类的属性进行显示初始化。
7.在进行子类构造函数的特定初始化。
8.初始化完毕后,将地址值赋值给引用变量。
**/
class Fu{
int num = 4;
void show1(){
System.out.println("fu show run");
}
}

class Zi extends Fu{
int num = 5;
void show(){
System.out.println(num+"......"+super.num);
}
void show1(){
System.out.println("zi show run");
}
}

public class ExtendDemo2 {
public static void main(String[] args) {

Zi z = new Zi();
z.show();
z.show1();
//z.show2();
}
}


内存图表现形式:



-------------------------------------------------------------------------------------------------------------------------

二.多态与继承特性

一个类方法重写,多个类继承关系方法覆写,体现多态性质
某一种事物存在的多种体现形态。

多态自始至终都是子类对象在做着变化。

多态的体现:

1.父类的引用指向子类的对象(子类对象类型提升,自动向上转型)

2.父类的引用页可以接受自己的子类对象,(向下转型,需要强制类型转换)

多态的前提:必须是类与类之间有关系,要么继承,要么实现。

多态的好处:

1.多态大大提高了程序的扩展性

2.通常还有一个问题在覆盖
eg:多态判断
class Animal
{
}

class Cat extends Animal
{
}

class Test
{
Animal animal = new Cat();//子类对象类型提升,自动向上转型
Cat cat = (Cat)animal;//父类引用转换为子类类型,向下转型需要强制类型转换
}
eg:多态体现
abstract class Animal{

abstract void eat();

}

class Dog extends Animal{

void eat(){

System.out.println("啃骨头");

}

void lookHome(){

System.out.println("看家");

}

}

class Cat extends Animal{

void eat(){

System.out.println("吃鱼");

}

void catchMouse(){

System.out.println("抓老鼠");

}

}

public class DuoTaiDemo {

public static void main(String[] args){

Animal a = new Cat();对象共性,都是动物

method(a);

method(new Dog());

}

public static void method(Animal a){

a.eat();

}

}


java保留了这种机制用另一种体现形式来完成表示多实现。

java支持多层继承,通过接口实现,也就是继承体系。

父类与子类中变量关系

子类继承父类后会拥有父类的成员,只不过有些成员不可见。

加载顺序:先加载父类成员后加载子类成员。

子父类中的变量:

如果子类中出现非私有的同名成员变量时,子类要访问本来变量用this,访问父类中的同名变量用super。

父类与子类中函数

当子类中出现和父类一模一样的函数(参数列表,返回值)时,当子类对象调用该函数,会运行子类函数的内容,如同父类被覆盖一样。这种情况是函数的另一种特性,重写(覆盖)。

覆盖:

1.子类覆盖父类,必须保证子类方法权限大于等于父类方法权限,才可以覆盖,否则编译失 败。

2.静态只能覆盖静态。因为静态优先于对象存在。

3.如果子类方法与父类私有方法同名,无法重写但不会报错,是一个新方法。

重载

当一个类中出现方法名相同,参数列表不同的方法时,被称为重载。重载可以改变返回值,因为它只看参数列表和名称。

-------------------------------------------------------------------------------------------------------------------------

三.封装特性

隐藏实现细节,并对外提供公共的访问方式。

函数或者类都是一个封装体。

特点:

1,隔离的变量。

2,便于使用。

3,提高复用。

私有在源代码中的使用就是在本类中有效。

通常会将成员变量xxx私有化,并对外提供对应的setXxx getXxx方法对其进行访问。

其实目的就是成员变量访问进行控制。 让成员的访问具备可控性,提高了程序的健壮性。

私有仅仅是封装的体现形式之一而已
eg:
public class Test{
private int a,int b;
public int getA(){
return this.a;
}
public void setA(int a){
this.a = a;
}
}


-------------------------------------------------------------------------------------------------------------------------

四.关键字(this,super,static,final)

this:代表的是对象。哪个对象调用了this所在的函数,this就代表哪个对象。

用法体现

1,当成员变量和局部变量同名时,可以用this区别。

2,当构造函数中调用本类其他构造函数时,可以用this完成。 this(实际参数);

这种调用必须定义在构造函数的第一行。初始化动作先完成。

应用:只要在定义功能时,用到了本类对象,那么就使用this来表示。

static关键字:

特点:

1,修饰成员。,

2,随着类加载,随着类消失。

3,优先于对象。

4,用类名直接访问

使用注意事项:

1,静态方法只能访问静态,静态有访问局限性。

2,静态方法中不能有this super关键字。

3,主函数是静态的

什么时候使用静态?

1,当成员变量的数据各个对象都相同时,可以用static修饰,让多个对象共享。

2,函数如果访问了特有数据(非静态成员变量),该函数是非静态的。

函数如果没有访问特有数据,那么该函数就可以静态修饰
final 关键字
/*
final : 最终。作为一个修饰符,
1,可以修饰类,函数,变量。
2,被final修饰的类不可以被继承。为了避免被继承,被子类复写功能。
3,被final修饰的方法不可以被复写。
4,被final修饰的变量是一个常量只能赋值一次,既可以修饰成员变量,有可以修饰局部变量。
当在描述事物时,一些数据的出现值是固定的,那么这时为了增强阅读性,都给这些值起个名字。方便于阅读。
而这个值不需要改变,所以加上final修饰。作为常量:常量的书写规范所有字母都大写,如果由多个单词组成。
单词间通过_连接。
5,内部类定义在类中的局部位置上是,只能访问该局部被final修饰的局部变量。

*/

class Demo
{
final int x = 3;
public static final double PI = 3.14;
final void show1()
{}
void show2()
{
final int y = 4;
System.out.println(3.14);
}
}
class SubDemo extends Demo
{
//void show1(){}
}
class FinalDemo
{
public static void main(String[] args)
{
System.out.println("Hello World!");
}
}


代码块:
1,局部代码快。

对局部变量的生命周期进行控制。
eg:
public void load(){
{
int i = 0,y =0;
}
}


2,构造代码块。

对所有对象进行初始化。
eg:
public class Test{

{

}
public void methodA(){

}
public void methodB(){

}
}


3,静态代码块。

对类进行初始化
/*
静态代码块。
格式:
static
{
静态代码块中的执行语句。
}

特点:随着类的加载而执行,只执行一次,并优先于主函数。
用于给类进行初始化的。

*/

class StaticCode
{
int num = 9;
StaticCode()
{
System.out.println("b");
}

static
{
System.out.println("a");
}
{
System.out.println("c"+this.num);
}

StaticCode(int x)
{
System.out.println("d");
}
public static void show()
{
System.out.println("show run");
}
}

class StaticCodeDemo
{
static
{
//System.out.println("b");
}
public static void main(String[] args)
{
new StaticCode(4);//a c d
//new StaticCode();
//new StaticCode();
//System.out.println("over");
//StaticCode.show();
//StaticCode s = null;
//s = new StaticCode();

//StaticCode.show();

}
static
{
///System.out.println("c");
}
}


-------android培训java培训、期待与您交流!
----------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐