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

黑马程序员——java基础-面向对象(二)

2015-06-11 07:10 507 查看
-------
android培训、java培训、期待与您交流! ----------

第一节:继承

一、继承的简述

1、继承的概念:类的继承是指在一个现有类的基础上去构建一个新的类,构建出来的新类被称作为子类,现有的类被称为父类,子类会自动拥有父类所有可继承的属性和方法。

2、java中如何表示继承及格式?

(1)、用关键字extends来表示

(2)、格式是:class 子类名 extends 父类名 {}

3、继承的好处

(1)、提高了代码的复用性

多个类相同的成员可以放到同一个类中。

(2)、提高了代码的维护性

如果功能的代码需要修改,修改一处即可。

(3)、让类与类之间产生了关系,是多态的前提

其实这也是继承的一个弊端:类的耦合性很强。

4、继承的弊端

(1)、继承的出现让类的耦合性增强,这样的话他们之间无论哪个类改变,都会影响与它相关的类。

(2)、继承的出现打破了封装性

5、继承的特点

(1)、java中只支持单继承。(导致调用多父类中的相同功能时,出现调用的不确定性)

(2)、java中可以多层继承。

6、继承的注意事项

(1)、子类只能继承父类所有非私有的成员(成员方法和成员变量)其实这也体现了继承的一个弊端:打破了封装性。

(2)、子类不能继承父类的构造方法,但是可以通过super关键字去访问父类构造方法。

(3)、不要为了部分功能而去继承。

二、在子父类中,成员的特点

1、成员变量

(1)、当子类的成员变量名与父类的成员变量名不一样时,调用谁就是谁。

(2)、当子类的成员变量名与父类的成员变量名一样时,子类的访问变量时的查找顺序是先是子类成员变量(省略了this.假如写的是super.就会直接找父类)----->父类成员变量---->在找不到就报错。

2、构造方法

(1)、子类的构造方法默认访问父类的无参的构造方法,目的是为了子类访问父类数据的初始化。

(2)、假如父类中没有无参的构造方法,子类要用super自定义一个调用有参的构造,子类是通过this来调用本身的其他构造,但至少要有一个访问父类的构造。

3、成员方法

(1)、当子类的成员方法名和父类的成员方法名不一样时,调用谁就是谁。

(2)、当子类的成员方法名和父类的成员方法名一样时,子类访问成员方法的顺序是先是子类成员方法------>父类的成员方法------->找不到就报错。(也就是发生覆盖了)

4、代码体现

//定义一个类 ,人类
class Person
{
//定义两个变量
int count=10;
int sum=88;
//构造函数,如果子类调用了此函数就会打印出语句
Person()
{
System.out.println("调用======person");
}
//定义了两个方法
public void run()
{
System.out.println("成功=========person");

}
public void show()
{
System.out.println("调用成功----------person");
}

}
//定义了一个学生类来继承人
class Student extends Person
{
//定义了 一个变量与父类的变量名同名的情况
int sum=0;
String name;
//自定义了一个构造方法
Student(String name)
{
this.name=name;
}
//定义了一个与父类一模一样的方法
public void show()
{
System.out.println("调用成功----------student");
}
public void run1()
{
System.out.println("成功=========student");
}

}
class Demo1
{
public static void main(String[] args)
{
//创建学生类对象
Student str=new Student("张三");
//打印出变量名不同的情况
System.out.println(str.count);
//打印出变量名相同的情况
System.out.println(str.sum);
//打印出方法名不相同的情况
str.run();
//打印出方法名相同的情况
str.show();

}
}



三、覆盖的理解

1、当子父类中出现成员函数一模一样的情况,会运行子类的函数。这种现象,称为覆盖操作。这时函数在子父类中的特性。

2、函数的两个特性

(1)、重载。同一个类中。overload。

(2)、覆盖。子类中。覆盖也称为重写,覆写。override。

3、覆盖注意事项

(1)、子类方法覆盖父类方法时,子类权限必须要大于等于父类的权限。

(2)、静态只能覆盖静态,或被静态覆盖。

(3)、父类中的私有方法不能被重写。

4、this和super的区别

(1)、this:代表一个本类对象的引用。

(2)、super:代表一个父类空间。

四、final关键字

1、final是最终的意思,它是一个修饰符,可以修饰类,方法,变量。

2、final修饰类,方法,变量个是什么特点

(1)、final修饰的类不可以被继承。

(2)、final修饰的方法不可以被覆盖。

(3)、final修饰的变量是一个常量,只能赋值一次。

3、为何用final修饰变量呢?

原因是如果程序中有一个数据是固定不变的,直接用的话,这样代码的阅读性差,就在这个变量前加上final固定。写法规范:常量所有字母都大写,多个单词,中间用_连接。

第二节:抽象类

一、抽象类的简述

1、对抽象类的理解:当把许多共性的东西提取到一个类中,有时候这些共性的东西,方法声明一样,但是方法体不同(实现每个对象的内容不同),就把没有具体方法体的方法是抽象方法,在一个类中有抽象方法,那么该类就必须为抽象类。

2、抽象类的特点:

(1)、抽象类和抽象方法必须用abstract关键字修饰

格式:

abstract class 类名 {}

public abstract void show();

(2)、抽象类不一定有抽象方法,有抽象方法的类一定是抽象类。

(3)、抽象类不能实例化。

(4)、抽象类的子类

(4).1 是一个抽象类。

(4).2 是一个具体类。这个类必须重写抽象类中的所有抽象方法。

3、抽象类中常见问题?

(1)、抽象类中有构造函数吗?

这个一定有,构造函数用于给子类对象进行初始化。

(2)、抽象类可以不定义抽象方法吗?

这个是可以的,目的是不让该类有创建实例对象。(例如:AWT的适配器对象就是这种类,类中的方法有方法体,但是方法体为空)

(3)、抽象关键字不可以和那些关键字共存?

(3).1 private 不可以(原因:如果抽象方法加上私有的话,子类无法访问,也就不能复写了,而抽象方法需要复写)

(3).2 static 不可以(原因:如果抽象方法加上静态的话,就可以被类名调用,抽象方法运行就没什么意义)

(3).3 final 不可以(原因:被final修饰的类不能被继承,方法不能被复写,而抽象类和抽象方法需要被继承和复写)

(4)、抽象类一定是个父类吗?

这个是必须的,因为需要子类复写其方法后才可以对子类实例化。

4、抽象类和一般类的区别

(1)、一般类有足够的信息描述事物。

抽象类描述事物的信息有可能不足。

(2)、一般类中不能定义抽象方法,只能定非抽象方法。

抽象类中可定义抽象方法,同时也可以定义非抽象方法。

(3)、一般类可以被实例化。

抽象类不可以被实例化。

(4)、抽象类和一般类都是用来描述事物的,都在内部定了成员。

二、抽象类的成员特点

1、成员变量

(1)、可以有变量

(2)、也可以有常量

2、成员方法

(1)、可以有抽象的方法。目的是:限定子类必须完成某些动作。

(2)、可以是非抽象的方法。目的是:提高代码的复用性。

3、构造方法

(1)、有构造方法,但是不能实例化,作用:用于子类访问父类数据的初始化。

代码体现

//假如我们在开发一个系统时需要对员工进行建模,员工包含 3 个属性:姓名、工号以及工资。经理也是员工,除了含有员工的属性外,另为还有一个奖金属性。
//请使用继承的思想设计出员工类和经理类。要求类中提供必要的方法进行属性访问。
class Demo1
{
public static void main(String[] args)
{//创建员工对象
Worker w=new Worker("王五",12234,3000);
//创建经理对象
Manager m=new Manager("张三",13200,4000,1000);
//调用员工的工作
w.work();
//调用经理的工作
m.work();

}
}
//定义一个抽象的工人类
abstract class Employee
{
//私有三个属性
private String name;
private int id;
private int pay;
//对子类进行初始化
Employee(String name,int id,int pay)
{
this.name=name;
this.id=id;
this.pay=pay;

}
//抽象的方法
public abstract void work();
}
//自定义一个员工类继承抽象的工人类
class Worker extends Employee
{
//员工类已初始化就具备的属性
Worker(String name,int id,int pay)
{
//访问父类
super(name,id,pay);
}
//复写父类中的抽象方法
public void work()
{
System.out.println("工人工作了");
}

}
//自定义一个经理类来继承抽象的工人类
class Manager extends Employee
{
//经理特有的属性
private int bonus;
//经理的构造方法
Manager(String name ,int id,int pay,int bonus)
{
//访问父类的属性
super(name,id,pay);
//自己独特的属性
this.bonus=bonus;
}
//复写父类中的方法
public void work()
{
System.out.println("经理开始工作了");
}
}



第三节:接口

一、接口的简述

1、接口的概述: 如果一个抽象类中的所有方法都是抽象的,则可以将这个类用另一种方式来定义,即接口。

2、接口的特点

(1)、接口用关键字interface表示

格式:interface 接口名 {}。

(2)、类实现接口用implements表示

格式:class 类名 implements 接口名 {}

(3)、接口不能实例化(接口的实例化是通过多态来完成的)

(4)、接口的实现类

(4).1 是一个抽象类。

(4).2 是一个具体类,这个类必须重写接口中的所有抽象方法。

二、接口成员特点

1、成员变量

(1)、只能是常量

(2)、默认修饰符 public static final

2、构造方法

(1)、接口没有构造方法,主要因为接口是扩展功能的,而没有具体存在。

3、成员方法

(1)、只能是抽象方法

(2)、默认修饰符 public abstract

三、类与类,类与接口,接口与接口

1、类与类

继承关系,只能单继承,但是可以多层继承

2、类与接口

实现关系,可以单实现,也可以多实现。还可以在继承一个类的同时实现多个接口

3、接口与接口

继承关系,可以单继承,也可以多继承

四、抽象类和接口的区别

1、相同点:

(1)、都是不断向上抽取而来的。

2、成员区别

(1)、抽象类 变量,常量;有构造方法;抽象方法,非抽象方法

(2)、接口 常量;抽象方法

3、关系区别

(1)、类与类 继承,单继承

(2)、类与接口 实现,单实现,多实现

(3)、接口与接口 继承,单继承,多继承

4、设计理念区别

(1)、抽象类的继承,是is a关系,类负责事物共性基本功能。

(2)、接口的实现是 like a 关系,接口负责的是事物扩展功能。

代码体现

//定义一个喝酒的接口
interface Beer
{
void beer();
}
//自定义抽象的人类
abstract class Person
{
//抽象的工作方法
public abstract void work();
//一般方法
public void sleep()
{
System.out.println("睡觉");
}
}
//定义一个工人类继承抽象类又能实现喝酒的方法
class Worker extends Person implements Beer
{
//覆盖接口中的方法
public void beer()
{
System.out.println("大碗的喝");
}
//覆盖抽象类中的方法
public void work()
{
System.out.println("上班");
}
}
class Demo1
{
public static void main(String[] args)
{
//创建一个工人类的对象
Worker w=new Worker();
w.beer();//调用和酒的方法
w.work();//调用工作的方法
w.sleep();//调用父类中的方法

}
}




第四讲:多态

一、多态的简述

1、多态概述:某一个事物,在不同时刻表现出来的不同状态。

例如:猫可以是猫的类型,猫 m = new 猫();同时猫也是动物的一种,也可以把猫称为动物,动物 d = new 猫()。简单说:就是一个对象对应着不同类型。

2、多态在代码中的体现

父类或者接口的引用指向其子类的对象。

3、多态的好处

提高了代码的扩展性,前期定义的代码可以使用后期的内容。

4、多态的弊端

前期定义的内容不能使用(调用)后期子类的特有内容。

5、多态的前提

(1)、有继承或者实现关系。

(2)、有方法重写。

(3)、有父类或者父接口引用指向子类对象。

6、多态的分类:

(1)、具体类多态

class Fu {}

class Zi extends Fu {}

Fu f = new Zi()

(2)、抽象类多态

abstract class Fu {}

class Zi extends Fu {}

Fu f = new Zi()

(3)、接口多态

interface Fu {}

class Zi implements Fu {}

Fu f = new Zi()

7、多态中的转型

(1)、向上转型:将子类型隐藏。就不用使用子类的特有方法。

从子到父

(2)、向下转型:就是子类的特有的方法。注意:一定要instanceof判断类型,避免ClassCastException

从父到子

二、多态中的成员访问特点

1、成员变量。

编译时:参考引用型变量所属的类中的是否有调用的成员变量,有,编译通过,没有,编译失败。

运行时:参考引用型变量所属的类中的是否有调用的成员变量,并运行该所属类中的成员变量。

简单说:编译和运行都参考等号的左边。

作为了解。

2、成员函数(非静态)。

编译时:参考引用型变量所属的类中的是否有调用的函数。有,编译通过,没有,编译失败。

运行时:参考的是对象所属的类中是否有调用的函数。

简单说:编译看左边,运行看右边。

因为成员函数存在覆盖特性。

3、静态函数。

编译时:参考引用型变量所属的类中的是否有调用的静态方法。

运行时:参考引用型变量所属的类中的是否有调用的静态方法。

简单说,编译和运行都看左边。

其实对于静态方法,是不需要对象的。直接用类名调用即可。

代码体现

//电脑运行的实例
class Demo1
{
public static void main(String[] args)
{
//创建电脑的对象
Computer c=new Computer();
//并调用方法,来让电脑运行
c.run();
//往电脑上插入键盘
c.usb(new KeyBoard());
//往电脑上插入鼠标
c.usb(new Mouse());
}
}
//创建一个usb的接口,里面定义了两个抽象的方法
interface USB
{
void open();
void close();
}
//定义一个键盘来实现usb
class KeyBoard implements USB
{
//覆盖打开的方法
public void open()
{
System.out.println("键盘已经打开");
}
//覆盖关闭的方法
public void close()
{
System.out.println("键盘已经关闭");
}
}
//定义一个鼠标来实现usb
class Mouse implements USB
{
//覆盖打开的方法
public void open()
{
System.out.println("鼠标已经打开");
}
//覆盖关闭的方法
public void close()
{
System.out.println("鼠标已经关闭");
}

}
//定义一个电脑类
class Computer
{
//定义一个电脑运行的方法
public static void run()
{
System.out.println("电脑运行");
}
//预留一个usb的接口,这也就是多态
public static void usb(USB U)
{
//如果有对象就调用方法
if (U!=null)
{
U.open();
U.close();
}

}
}




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