----------------------class="Apple-converted-space">?android开发、java培训、期待与您交流! ----------------------
?
1.面向对象概念
?
??
??
??
??
??
?什么是面向对象,面向对象与面向过程的区别?
?
??
??
??
??
??
??
??
??
??
??
?面向对象是相对面向过程而言,面向过程和面向对象都是一种思想,面向过程注重的是过程, 强调的是功能行为,面向对象就是将功能封装进对象,强调的是具备了功能的对象。面向对象 简单地说就是站在对象的角度考虑问题。
?
?
??
??
??
??面向对象的几个
例子:(比较重要一定要
理解)
?
??
??
??
??
??
??
??a.账户的存取
?
??
??
??
??
??
??
??
??
??
??
?面向对象简单地说就是站在对象的角度考虑问题,比如说有一个账户,我们可以对其进行存款和取款的操作,以面向过程的思想考虑就是我们操作此账户,来手动的完成存和取的动作。而以 面向对象的思想来考虑的话,就是我们可以把存款和取款这两个功能封装在账户中,每当我们要存或取的时候,就直接调用账户就行了。
?
??
??
??
??
??
??
??b.冰箱的开关
?
??
??
??
??
??
??
??
??
??
??
?要把大象放进冰箱,要分为三个步骤,把冰箱门打开,把大象放进去,把冰箱门关上。首先开门,放东西进去,关门,这三步都是过程吧,以面向过程的思想就是我们要去执行这三个过程,每一次往里放东西都要执行这三个步骤,这样是比较麻烦的,这样考虑下,加入我们把这三个 功能的方法装进冰箱里,就是说冰箱具有自动开关等功能,我们再需要往冰箱里放东西,是不是就可以直接找冰箱这三个步骤让它来做(因为它具有了这三个功能)就行啦。
?
?
??
??
??
??
??
??
??
??
??
??再简单点说就是,比如有一个大筐里面放了编写程序所需要的所有功能(也就是函数),再假如 说此时我们要做一件事,过程中需要调用好多功能,这时我们是不是就需要在那个大筐里找我们所 需要的功能啊,这样是比较麻烦的。然后我们再想是不是可以这样,这个大筐中的功能肯定有好多共性的,并且同属于一个事物的(比如说冰箱的开关等),这时我们是不是就可以把这些共性的功能放到另一个小筐里啊,等下次再用的时候直接找这个小框就行了,反正那些功能是小筐特有的,那就直接让它做就ok了,这样是不是就省了很多事儿啊。 ?
??
?
??
??
??
??
??
??
面向对象的特点有哪些?
?
??
??
??
??
??
??
??
?1、 面向对象是一种思想
2、可以将复杂的事情简单化
3、将
程序员从执行者转换成了指挥者
?
为什么需要面向对象?
面向对象与人们
习惯的思维方法一致,使程序代码更加容易让人理解和接受,开发效率高,并且有利与后期修改和维护;面向对象能提高代码的复用性,而面向过程就不行,好比有一个功能, 面向过程的程序设计时如果有很多地方都用到这个功能,那好多地方的代码肯定都是重复的,而用面向对象的话,就直接调用(对象.功能) 就行了,够简洁吧。
?
??
2.类与对象的区别
?
??
??
??
??
??
??
??
??在开发的过程中其实就是在找对象用,比如说要用一个功能,就找其对应的对象,如果没有的话,就 自己造一个对象,把功能封装进去。然后再指挥该对象做事情。
类:就是具体事物的描述,就是描述对象的,类是抽象的,就像一张图纸。
对象:就是实实在在具体的事物,类就是描述它的。new一个类就出来一个对象实体在java中,描述就是class定义的类,对象就是java堆
内存中new出来的实体。因为一个对象里含有很多数据,我们说含有很多数据的就用实体来存储,就像数组一样
?
怎么定义一个类?
定义一个类其实就是在描述一个事物,而一个事物通常都会有属性与行为,就像一只鸭子,眼睛 腿就是 属性,游泳就是行为。属性对应的就是类中的变量,行为对应的就是类中的函数。 一个类要想独立运行的前提是要有主函数,而建立一个类不需要独立运行的话可以不写主函数
?
??
类中的成员有:成员变量和成员函数
成员变量与局部变量的区别是什么?
成员变量作用于整个类中,而局部变量作用于函数中或语句中,用过后空间会被自动释放。成员变量在栈内存中,而局部变量存在于堆内存中,因为它是因对象存在而存在的,你说人都没了定义人的年龄有什么用。局部变量没有默认初始化值,而成员变量有默认初始化值。
?
?
??
??
??
??
??
??
??
?定义一个类:
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
?class Car//对Car这类事物进行描述
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
?{
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??String color = "red";//在整个类中有效
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??int num = 4;
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??void show()
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??{
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
?System.out.println("color="+color+"..num="+num);
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??}
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
?}
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??class CarDemo
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??{
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
?public static void main(String[] args)
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
?{
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??Car c = new Car();//new一个汽车实体
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??c.color = "black";//对对象(汽车)的属性进行修改
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??c.show();//使用对象的功能。
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
?}
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
?}
?
?
??
??
??
??
??
??匿名对象
?
??
??
??
??
??
??
??
??
??什么是匿名对象?
?
??
??
??
??
??
??
??
??
??
??
??匿名对象是对象的简化形式
?
??
??
??
??
??
??
??
??
??
??
?例如:Car c = new Car();c.show();可以写成new Car().show;这就是匿名对象直接调用show方法
?
?
??
??
??
??
??
??
??
??
?什么情况下使用匿名对象?
?
??
??
??
??
??
??
??
??
??
??
??
??
?1.当对对象的方法只调用一次时(调用变量没
意义),可以用匿名对象来完成,这样写比较简化。
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??如果对一个对象进行多个成员调用,必须给这个对象起个名字。
?2.可以将匿名对象作为实际参数进行传递。
?
??
??
??
??
??
??
??
??
??
??
??
??代码:
?
??
??
??
??
??
??
??
??
??
??
??
??
?
class Car
{
String color = "红色";//描述颜色
int num = 4;//描述轮胎数
void run()//运行行为。
{
System.out.println(color+".."+num);
}
}
class CarDemo
{
public static void main(String[] args)
{
//创建一匿名对象调用属性
new Car().num = 5;
//又创建一匿名对象,此时上面创建的堆内存中的实体已经成垃圾了
new Car().color = "blue";
new Car().run();//创建匿名对象调用属性没意义,因为调过来了没人用
Car q = new Car();
show(q);//创建一有名对象,调用show方法
//上面两步可以简化成这样:
show(new Car());//匿名对象当参数传入
}
public static void show(Car c)//传入一个car类型的参数
{
c.num = 3;
c.color = "black";
c.run();
}
}
??
?
??
??
??
??
?对象与匿名对象在内存中的结构如下图:
黑马程序员——面向对象之封装 - hm_yong_jie - hm_yong_jie的博客
?
?3.封装
什么是封装?
面向对象三大特征之一,是指隐藏对象的属性和实现细节,仅对外提供 公共访问方式。就是说我们如果调用一个功能的话,我们要的就是它的结果,而它怎么实现的和我们没关系。函数就是最小的封装体。
1、比如说我们使用的电脑,什么上网啊,玩游戏啊,我们使用的只是它的功能,有必要直到它内部是怎么实现的吗?有必要打开
机箱看看里面都是什么吗?即使打开看了也不懂,还有可能把电脑给捯饬坏。
?
使用封装有什么好处呢?
1.提高
安全性 ?把主板啊,cpu啊封装在机箱内,避免我们这些不懂的人乱碰乱改,是不是安全了?
2.提高重用性 ?
3.将变化隔离 ?这次机箱里面的部件是这样,等过些
日子又出来一新电脑,里面的东西是不是变啦, 怎么变得我们知道,也不需要知道,这就是将变化隔离 ?
??
??
??
??
??
???
4.便于使用 ?
?我们不需要知道电脑的内部结构了,直接拿过来就能用,是不是很方便
?
??
??
??
??
??
???
private(私有)
关键字
封装的目的就是
限制对类里面成员的访问,隐藏类的实现细节,那么要限制类的外部对类成员的访问,可以用访问修饰符private来修饰属性。
1.private是一个权限修饰符
2.用于修饰成员(成员变量和成员函数)
3.被私有化的成员只在本类中有效用private将成员变量私有化,对外提供对应的set,get方法对其进行访问,提高对数据访问的安全性。
?
?
??
??
??
??
??
??
??
??
??
?代码:
?
??
??
??
??
??
??
??
??
??
??
??
??
?
class Person
{
//把person类中的age属性私有化,在其他类中将不能访问它,像new Person().age是不行的
private int age;
//在这个类中不让访问age,但是你得提供一个让别人访问的方法啊,就是下面这样
public void setAge(int a)
{
if(a>0 && a<130)
{
age = a;
speak();
}
else
System.out.println("feifa age");
}
public int getAge()
{
return age;
}
//类中的方法被私有化,在别的类中也是访问不到的,只在本类中有效
private void speak()
{
System.out.println("age="+age);
}
}
??
?
?4.
构造函数
什么是构造函数?
构造函数是类中一种特殊的函数,它方法名誉类名相同,没有返回
值类型,也不需要void,构造 函数的作用在于
创建对象的时候初始化对象,给实例化对象的成员变量赋初始值。
?
构造函数的特点是什么?
1.函数名与类名相同 ??
2.不用定义返回值类型(void也是一种返回值类型)
3.不可以写return语句 ?
?函数中连返回值类型都没有还用得着把return语句吗?
?
构造函数与一般函数有什么区别?
1.首先在写法上就不同,然后在运行上也有不同。构造函数是在对象一建立就运行。给对象初始化。而一般方法是对象调用才执行,是给对象添加对象具备的功能。
2.一个对象建立,构造函数只运行一次。而一般方法可以被该对象调用多次。可以理解为构造函数就是为了创建对象,对象一创建完它的使命就完成了
??
什么时候用构造函数?
当分析事物时,该事物存在具备一些特性或者行为,就是该食物一定具备哪些行为(就像小孩 一出生就哭)那么将这些内容定义在构造函数中。然后再考虑写构造函数的时候是否需要未知参数参与运算。
?
构造函数有什么用?
构造函数是用来给对象进行初始化的,对象一建立就会调用与之对应的构造函数,
注意:
说是对象一初始化就要调用构造函数,那前些日子
写代码也没斜构造函数啊?这是因为当 一个类中没写构造函数时,系统会帮你自动加一个空参数的构造函数,方便于对象初始化, 否则对象是建立不出来的。总之要记着,一个类中如果没有构造函数,那这个对象是肯定new不出来的。如果new对象时,类中没有与它对应的构造函数,这样也是创建不出对象的。 如果你自己建立了一个构造函数,那默认的构造函数就没了。
?
??
??
??
??
??
??
??
???
部分代码:
?
??
??
??
??
??
??
??
??
??
??
??
??
class Person
{
private String name;
private int age;
//所以对象一创建就会按下面与之对应的构造函数来初始化对象
Person()
{
System.out.println("A: name="+name+",,age="+age);
}
//构造函数也是函数它也可以重载
Person(String n)
{
name = n;
System.out.println("B: name="+name+",,age="+age);
}
Person(String n,int a)
{
name = n;
age = a;
System.out.println("C: name="+name+",,age="+age);
}
}
class PersonDemo2
{
public static void main(String[] args)
{
//对应第一种构造函数new出来的人什么都没有
Person p1 = new Person();
//对应第二种构造函数new出来的人有名字没年龄
Person p2 = new Person("lisi");
//对应第三种构造函数new出来的人有年龄有姓名
Person p3 = new Person("lisi",0);
}
}
??
构造代码块:
作用:给对象进行初始化,对象一创建就运行,并且优先于构造函数
疑问:构造函数不就是给对象进行初始化的吗,为什么还要用构造代码块啊?和构造函数的区别: ?
??
??
??
??
???
??
??
??
??
??
?上面不是说有很多种构造函数吗,就是说创建对象的时候能创建很多种类型的对象,每一种构造函数都是给其对应的那类对象初始化,而构造代码块是给所有种类的对象都初始化,也就是说把所有类型对象的共同点给抽出来写在构造代码块里,这样就不用在每种构造函数都写了,比如每一种小孩生下来都哭,那么这样就可以把哭的行为写进构造代码块,是不是比在每个构造函数里都写显得轻松啊,就像是以前说的如果好几段代码里都有相同代码的时候,那就把这些相同的抽出来写进一个函数中,不就 省的来回的重复写啦。 ?
??
??
??
??
???
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
?
5.this关键字
?
??
??
??
??
??
??
??
??
?class Person
?
??
??
??
??
??
??
??
??
?{
?
??
??
??
??
??
??
??
??
??
??
??
??
??
?private String name;//此name是成员变量?
?
??
??
??
??
??
??
??
??
??
??
??
??
??
?public void String setName(String name)//此name是往函数中传的参数是局部变量
?
??
??
??
??
??
??
??
??
??
??
??
??
??
?{
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
?//this.成员变量 = 局部变量
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??this.name ?= ?name;
?
??
??
??
??
??
??
??
??
??
??
??
??
??
?}
?
??
??
??
??
??
??
??
??}?
从以上代码看出this是用来解决成员变量和局部变量同名似的问题。
this:看上去,是用于区分局部变量和成员变量同名情况。
this:就代表本类的对象,到底代表哪一个呢?
this代表它所在函数所属对象的引用。
简单说:哪个对象在调用this所在的函数,this就代表哪个对象。
?
??
??
??
??
??
??
???
类中成员之间的互相调用的时候其实都是对象完成的,只不过是省略了this.。
?
??
??
??
??
??
??
??
??
??
?class Person
?
??
??
??
??
??
??
??
??
??
?{
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
?private String name;
?
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
?public void speak()
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
?{
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
?System.out.println("name="+this.name);//省略了this. ?
???
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
?}
?
??
??
??
??
??
??
??
??
??
?}
?
?this的应用:
当定义类中功能时,该函数内部要用到调用该函数的对象时,这时用this来表示这个对象。
但凡本类功能内部使用了了本类对象,都用this表示。
?
?
??
??
??
??
?this语句 :用于构造函数之间进行互相调用。
?
??
??
??
??
?this语句只能定义在构造函数的第一行。因为初始化要先执行。
部分代码: ?
?
??
??
??
??
??
??
??
??
??
??
??
??
??
class Person
{
private String name;
private int age;
Person(String name)
{
this.name =name;
}
Person(String name,int age)
{
this(name);//调用上一种构造函数,不过要写在第一行
this.age = age;
}
}
??
?6.static关键字
?
??
??
??
??
??
??
??
??
??
??static用于修饰成员(成员变量和成员函数),static修饰的是把所有new出来的对象共性的东西。
?
??
??
??
??
?参看下图:
黑马程序员——面向对象之封装 - hm_yong_jie - hm_yong_jie的博客
?
被修饰后的成员具备以下特点:
1.随着类的加载而加载 说明它的生命周期和类一样长,而一般成员是随着对象的存在而存在的
2.优先于对象存在 ?静态是先存在的,对象是后存在的。
3.被所有对象所共享
4.可以直接被类名调用
使用static时要注意:
1.
静态方法只能访问静态成员
2.静态方法中不可以写this,super关键字,静态修饰的对象先于构造函数存在,
3.主函数是静态的
?
什么时候使用静态?
因为静态修饰的内容有成员变量和函数。那就分两步下手:
什么时候定义静态变量(类变量)呢?
当对象中出现共享数据时,该数据被静态所修饰。对象中的特有数据要定义成非静态存在于堆内存中。
什么时候定义静态函数呢?
当功能内部没有访问到肺静态数据(对象的特有数据),那么该功能可以定义成静态的。
?
?
?静态代码块。
?
??
??
??
??
??
??
??
??
??
??
??
??格式:
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??static
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??{
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
?//静态代码块中的执行语句。
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??}
?
?
??
??
??
??
??
??
??
??
??
??
??
??特点:随着类的加载而执行,只执行一次,并优先于主函数。用于给类进行初始化的。
?
??
??
??
??
??
??
??
??
??
??
??
??优先级 ?高----------------------------------->低 ?
??
??
??
?
??
??
??
??
??
??
??
??
??
??
??
??
?静态代码块---- ?构造代码块----构造函数 ??
?
??
??
??
??
??
??
??
??
??
??
??
?class StaticCode
?
??
??
??
??
??
??
??
??
??
??
??
?{
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??StaticCode()
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??{
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
?System.out.println("b");
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??}
?
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??static//静态代码块,先于构造代码块和构造函数
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??{
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??System.out.println("a");
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??}
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
?//构造代码块,先于构造函数
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??{
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??System.out.println("c");
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??}
?
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??StaticCode(int x)
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??{
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??System.out.println("d");
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??}
?
??
??
??
??
??
??
??
??
??
??
??}
?
??
??
??
??
??
??
??
??
??
??
?class StaticCodeDemo?
?
??
??
??
??
??
??
??
??
??
??
?{
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
?public static void main(String[] args)?
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
?{
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
?new StaticCode(4);
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
?}?
?
??
??
??
??
??
??
??
??
??
??
?}
?
??
??
??
??
??
??
??
??
??
??
?打印结果:a ?c ?d
?
实例变量(成员变量)和类变量(static修饰的变量)的区别:
1,存放位置。
类变量随着类的加载而存在于方法区中。
实例变量随着对象的建立而存在于堆内存中。
2,生命周期:
类变量生命周期最长,随着类的消失而消失。
实例变量生命周期随着对象的消失而消失。
使用静态有哪些利弊?
利处:对对象的共享数据进行单独空间的存储,节省空间。没有必要每一个对象中都存储一份。可以直接被类名调用。
弊端:生命周期过长。访问出现局限性。(静态虽好,但是只能访问静态。)
?
???
对象初始化过程: ?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
???
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
???
Person p = new Person("zhangsan",20); ?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
该句话都做了什么事情? ?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
1,因为new用到了Person.class.所以会先找到Person.class文件并加载到内存中。
2,执行该类中的static代码块,如果有的话,给Person.class类进行初始化。
3,在堆内存中开辟空间,分配内存地址。
4,在堆内存中建立对象的特有属性。并进行默认初始化。
5,对属性进行显示初始化。
6,对对象进行构造代码块初始化。
7,对对象进行对应的构造函数初始化。
8,将内存地址付给栈内存中的p变量。 ?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
7.单例
设计模式
单例设计模式:解决一个类在内存只存在一个对象。
想要保证对象唯一新需要三步:
1,为了避免其他程序过多建立该类对象。先禁止其他程序建立该类对象
2,还为了让其他程序可以访问到该类对象,只好在本类中,
自定义一个对象。
3,为了方便其他程序对自定义对象的访问,可以对外提供一些访问方式。
?
??
??
??这三部怎么用代码体现呢?
?
?1,将构造函数私有化。
2,在类中创建一个本类对象。
3,提供一个方法可以获取到该对象。
?
?
??
??
??
??
??
??
??
??
??
??饿汉式
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??这个是先初始化对象。Single类一进内存,就已经创建好了对象。
?
??
??
??
??
??
??
??
??
??
??
??
??
??
?
class Single
{
private static Single s = new Single();
private Single(){}
public static Single getInstance()
{
return s;
}
}
??
?
?
??
??
??
??
??
??
??
??
??
??懒汉式
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
?对象是方法被调用时,才初始化,也叫做对象的延时加载。Single类进内存,对象还没有存在,只有调用了getInstance方法时,才建立对象。
?
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
class Single
{
private static Single s = null;
private Single(){};
public static Single getInstance()//双重判断 先判断是否为空,再判断锁,然后再判读是否为空
{
if(s==null)
{
synchronized(Single.class)
{
if(s==null)
s = new Single();
}
}
return s;
}
}
??
1.继承
?
??
??
?1、什么是继承?
?
??
??
??
??
??
??多个类中存在相同属性和行为时,将这些内容抽取到 单独一个类中,那么多个类无需再定
?
??
??
??
??
?义这些属性和行 为,只要继承单独的那个类即可。多个类可以称为子类,单独这个类称为父类
?
??
??
??
??
?超类。子类可以直接访问父类中的非私有的属性和行为。通过extends 关键字让类与类之间产生
?
??
??
??
??
?或者继承关系。如:class SubDemo extends Demo{}
-------------------------------------------------------------------------------------------------
?
??
??
??
??
?举个例子,比方说俩兄弟去露营,那这时候是不是要带帐篷,救生箱,睡袋什么的啊。但是哥俩
?
??
??
??
??
?每个人都带一份是不是就显得累赘啊,这个时候父亲看到了:"说我也去,我拿帐篷,救生箱什么
?
??
??
??
??
?的“。这样兄弟俩是不是就轻松了许多啊,不用每个人都拿那么多东西了,晚上睡觉的时候或者
?
??
??
??
??
?需要救生箱的时候到父亲那拿就行了。 ?这个父亲就相当于父类,俩兄弟就是子类,父类中都是
?
??
??
??
??
?子类所共有的,所以子类中就没必要再挨个定义了。只要不是父类私有的东西,子类都可以继承
?
??
??
??
??
?过来用,父类与子类之间通过 extends 来实现继承。
-------------------------------------------------------------------------------------------------
?
??
??
??
??
?通过继承可以使用其他类里的功能,但是千万不要为了使用其他类里的功能而随便继承,必须是
?
??
??
??
??
?类与类之间存在所属关系才能够继承,就像是你露营的时候不可能别人拿了个游戏机你为了玩个
?
??
??
??
??
?游戏,就随便认别人为父亲吧。像燕子麻雀等都能继承鸟类,但你不可能为了吃的功能去继承哺
?
??
??
??
??
?乳动物那一类吧。所属关系是 is a才能继承。is a(谁是谁里面的一员)。
?
-------------------------------------------------------------------------------------------------
?
??
??
?2、继承的特点是什么?
?
??
??
??
??
?Java只支持单继承,不支持多继承。一个类只能有一个父类,不可以有多个父类。因为多继承容
?
??
??
??
??
??易带来
安全隐患:当多个父类中定义了相同功能,当功能内容不同时,子类对象不确定要运行哪一
?
??
??
??
??
??个。但是java保留这种机制。并用另一种体现形式来完成表示。可以多实现
接口。
?
??
??
??
??
??
??class SubDemo extends Demo{} //正确
?
??
??
??
??
??
??class SubDemo extends Demo1,Demo2...//
错误
?
?
??
??
??
??
?Java支持多层继承(继承体系),就类似父亲-儿子-孙子的关系
?
??
??
??
??
??
??class A{}
?
??
??
??
??
??
??class B extends A{}
?
??
??
??
??
??
??class C extends B{}
?
?
??
??
??
??
?定义继承需要注意:
?
??
??
??
??
??
??
?不要仅为了获取其他类中某个功能而去继承
?
?
??
??
??
??
?类与类之间要有所属( " is a " )关系才能继承,xx1是xx2的一种。
-------------------------------------------------------------------------------------------------
?
??
??
?3.如何使用一个继承体系中的功能呢?
?
??
??
??
??
?在使用一个继承体系中的功能时,可以看一下这个体系中父亲类的功能是什么,因为父亲类中
?
??
??
??
??
?肯定是这个体系中最共性的东西,通过了解共性功能,就了解到这个体系的基本功能是什么了。
?
??
??
??
??
?但是在具体调用时,要创建最子类的对象,为什么呢?
?
??
??
??
??
?一是因为有可能父类不能创建对象,
?
??
??
??
??
?二是创建子类对象可以使用更多的功能,包括基本的也包括特有的。
?
?
??
??
??
?简单一句话:查阅父类功能,创建子类对象使用功能。?
-------------------------------------------------------------------------------------------------
?
??
??
?4.聚集关系
?
??
??
??
??
?java类与类之间的其它关系:
?
??
??
??
??
?聚集或者叫关联: 分为聚合和组合两部分
?
??
??
??
??
?聚合:
has a 一个班级由很多学生组成,学生与班级的关系就是组合。
?
??
??
??
??
?组合:事物的联系程度更紧密,例如心脏是人身体中的一部分,班级少一个人行,人缺了心脏不行。
-------------------------------------------------------------------------------------------------
?
??
??
?5.子父类中成员的特点
?
??
??
??
??
??
??类中成员包括:1,变量。2,函数。3,构造函数。
?
??
??
??
??a.那么子父类中的变量特点是什么呢?
?
??
??
??
??
??
??继承的时候,当子类和父类之间存在相同的成员变量时,子类要访问本类中的变量,用this,
?
??
??
??
??
??
??子类要访问父类中的同名变量,用super。比方说你本来有一个苹果,又从父亲那继承过来一
?
??
??
??
??
??
??个苹果,这个时候你要吃的话,就是吃自己的(this)还是父亲的(super);
?
??
??
??
??
??super 的使用和this的使用几乎一致。this代表的是本类对象的引用。super代表的是父类对象的引用。
?
??
?
??
??
??
??b.子父类中函数的特点
?
??
??
??
??
??
??当子类出现和父类一模一样的函数时,当子类对象调用该函数,会运行子类函数的内容。
?
??
??
??
??
??
??如同父类的函数被覆盖一样。就像孩子从父亲那继承过来说话的行为(函数),运行的时候,是
?
??
??
??
??
??
??自己说话的功能,而不是父亲的。
?
???
?
??
??
??
??
??
??这种情况是函数的另一个特性:重写(或覆盖)
?
??
??
??
??
??
??当子类继承父类,沿袭了父类的功能,到子类中,但是子类虽具备该功能,但是功能的内容却
?
??
??
??
??
??
??和父类不一致,这时,没有必要定义新功能,而是使用覆盖特殊,保留父类的功能定义,并重
?
??
??
??
??
??
??写功能内容。
?
?
???
?
??
??
??
??
??
??比如说你写了一个类,类中的功能(函数)什么的都很符合当时的需求,但是过了一段时间功能
?
??
??
??
??
??
??例的内容又改变了怎么办?不可能一遍又一遍的修改源代码,这时就可以再写一个类来继承这
?
??
??
??
??
??
??各类,然后再写一个与父类方法名一样的函数,来更新函数的功能,这就用到了覆盖。
?
??
??
??
??
??
??部分代码:
?
??
??
??
??
??
??
??
??class Tel//比如这个程序的功能当时就能打电话发信息
?
??
??
??
??
??
??
??
??{
?
??
??
??
??
??
??
??
??
??
??void show()
?
??
??
??
??
??
??
??
??
??
??{
?
??
??
??
??
??
??
??
??
??
??
??
??System.out.println("打电话");
?
??
??
??
??
??
??
??
??
??
??
??
??System.out.println("发信息");
?
??
??
??
??
??
??
??
??
??
??}
?
??
??
??
?
??
??
??
??
??
??
??
??}
?
??
??
??
??
??
??
??
??
?//一段时间后,又需要加一个上网的功能,这时不可能去改源代码或重新写一个程序这时只
?
??
??
??
??
??
??
??
??
?//需要再写个类继承上个类,然后重写父类的功能就行了,如果这个新功能用着不好,还可以
?
??
??
??
??
??
??
??
??
?//接着在用父类的
?
??
??
??
??
??
??
??
?class NewTel extends Tel//继承上个类
?
??
??
??
??
??
??
??
?{
?
??
??
??
??
??
??
??
??
??
?void show()//覆盖父类的方法
?
??
??
??
??
??
??
??
??
??
?{
?
??
??
??
??
??
??
??
??
??
??
??
?System.out.println("打电话");
?
??
??
??
??
??
??
??
??
??
??
??
?System.out.println("发信息");
?
??
??
??
??
??
??
??
??
??
??
??
?System.out.println("上网");
?
??
??
??
??
??
??
??
??
??
?}
?
??
??
??
??
??
??
??
?}
?
?
?
??
??
??
??
?使用覆盖时
需要注意哪些问题?
?
??
??
??
??
??
??1,子类覆盖父类,必须保证子类权限大于等于父类权限,才可以覆盖,否则编译失败。
?
??
??
??
??
??
??2,静态只能覆盖静态。
?
?
?
??
??
??
??
?重载与重写的区别:
?
??
??
??
??
??
??重载:只看同名函数的参数列表。
?
??
??
??
??
??
??重写:子父类方法要一模一样。就方法里面的内容不一样
?
?
??c.子父类中的构造函数的特点。
?
??
??
??
??
??在对子类对象进行初始化时,父类的构造函数也会运行,那是因为子类的构造函数默认第
?
??
??
??
??
??一行有一条隐式的语句 super();super():是访问父类中空参数的构造函数。而且子类中
?
??
??
??
??
??所有的构造函数默认第一行都是super();
?
?
??
??
??
??
??super关键字
?
??
??
??
??
??1.super和this的用法相同 ?
??
?
??
??
??
??
??2.this代表本类应用,super代表父类引用
?
??
??
??
??
??3.当子父类出现同名成员时,可以用super进行区分
?
??
??
??
??
??4.子类要调用父类构造函数时,可以使用super语句。
-------------------------------------------------------------------------------------------------
?
??
??
??
??为什么子类一定要访问父类中的构造函数呢?
?
??
??
??
??
??
??因为父类中的数据子类可以直接获取。所以子类对象在建立时,需要先查看父类是如
?
??
??
??
??
??
??何对这些数据进行初始化的。所以子类在对象初始化时,要先访问一下父类中的构造
?
??
??
??
??
??
??函数。如果要访问父类中指定的构造函数,可以通过手动定义super语句的方式来指定。
-------------------------------------------------------------------------------------------------
?
??
??
??
??子类的实例化过程:
?
?
??
??
??
??
??
?子类的所有的构造函数,默认都会访问父类中空参数的构造函数。因为子类每一个构造函数内的第一行都有一句隐式super();当父类中没有空参数的构造函数时,子类必须手 动通过super语句形式来指定要访问父类中的构造函数。子类的构造函数第一行也可以手动指定this语句来访问本类中的构造函数。子类中至少会有一个构造函数会访问父类中的构造函数。
?
??
??
??
?部分代码:
?
??
??
??
??
??
?class Fu?
?
??
??
??
??
??
?{
?
??
??
??
??
??
??
??
?int num ;//1.子类继承它之后,这个成员就能直接拿过去用了
?
??
??
??
??
??
??
??
?Fu()
?
??
??
??
??
??
??
??
?{
?
??
??
??
??
??
??
??
??
??
?num= 60;//2.但是拿过去之前得先看下父类是怎么初始化的啊
?
??
??
??
??
??
??
??
??
??
?System.out.println("fu run");
?
??
??
??
??
??
??
??
?}
?
??
??
??
??
??
??
??
?Fu(int ?x)
?
??
??
??
??
??
??
??
?{
?
??
??
??
??
??
??
??
??
??
?System.out.println("fu ...."+x);
?
??
??
??
??
??
??
??
?} ?
???
?
??
??
??
??
??
?}
?
?
??
??
??
??
??
?class Zi extends Fu
?
??
??
??
??
??
?{
?
??
??
??
??
??
??
??
?Zi()
?
??
??
??
??
??
??
??
?{
?
??
??
??
??
??
??
??
??
?//3.如果父类已经初始化过num=60了,那再在子类中初始化就有点多余了不是
?
??
??
??
??
??
??
??
??
??
??//num = 60?
?
??
??
??
??
??
??
??
??//4.所以子类初始化之前要先看下父类是怎么初始化的,默认是父类空参数的构造函数
?
??
??
??
??
??
??
??
??
??
??
?super(); ?
?
??
??
??
??
??
??
??
??//super(4);5.但是也可以自己指定用父类的哪个构造函数,无论哪种都必须在第一行
?
??
??
??
??
??
??
??
??
??
??
?System.out.println("zi run");
?
??
??
??
??
??
??
??
?}
?
??
??
??
??
??
??
??
?Zi(int x)
?
??
??
??
??
??
??
??
?{
?
??
??
??
??
??
??
??
??
??
?this();//6.子类中的构造函数也可用this语句访问本类的构造函数
?
??
??
??
??
??
??
??//super();7.有6的话,就不用再写父类的构造函数了,因为this()里已经做了这个的动作了
?
??
??
??
??
??
??
??
??
??
?System.out.println("zi..."+x);
?
??
??
??
??
??
??
??
?}
?
??
??
??
??
??
?}
?
?
??
??
??
??
??class ?
ExtendsDemo4
?
??
??
??
??
??{
?
??
??
??
??
??
??
??public static void main(String[] args)?
?
??
??
??
??
??
??
??{
?
??
??
??
??
??
??
??
??
??Zi z = new Zi(0);
?
??
??
??
??
??
??
??
??
??System.out.println(z.num);
?
??
??
??
??
??
??
??}
?
??
??
??
??
??}
-------------------------------------------------------------------------------------------------
?
??
?6.final关键字
?
?
??
??
??
??继承的缺点是破坏了封装性,人家本来一个类好好的,把里面的功能封装起来就是让你不用动
?
??
??
??
??里面的功能直接用就行了,你这把人家继承过来之后,不光用还能改,这样是不是封装性就打
?
??
??
??
??破了啊?要想不让别人改你的功能,可以用final来修饰类,这样别人就不能继承你了,如果一
?
??
??
??
??个类被别人继承之后觉得里面的个别功能你能重写,但是有的你不能重写,只是就可以用final
?
??
??
??
??来修饰那些不认别人重写的功能(函数)。
?
?
??
??
??
??final : 最终的意思。是一个修饰符,
?
??
??
??
??final的特点:
?
??
??
??
??
??
?1,可以修饰类,函数,变量。
?
??
??
??
??
??
?2,被final修饰的类不可以被继承。为了避免被继承,被子类复写功能。
?
??
??
??
??
??
?3,被final修饰的方法不可以被复写。
?
??
??
??
??
??
?4,被final修饰的变量是一个常量只能赋值一次,既可以修饰成员变量,有可以修饰局部变量。
?
??
??
??
??
??
??
??当在描述事物时,一些数据的出现值是固定的,那么这时为了增强阅读性,都给这些值起
?
??
??
??
??
??
??
??个名字。方便于阅读。而这个值不需要改变,所以加上final修饰。
?
??
??
??
??
??
??
??final常量:常量的书写规范所有字母都大写,如果由多个
单词组成。单词间通过_连接。
?
??
??
??
??
??
??
??
??
??
??
??
??如:public static final double PI = 3.14;
?
??
??
??
??
??
?5,内部类定义在类中的局部位置上时,只能访问该局部被final修饰的局部变量。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
2.继承(2)
?
??
??
?7.抽象类
?
??
??
??
??什么是抽象?
?
??
??
??
??
??
?抽象就是不具体的东西,就是将很多事物的共性的本质的抽取出来。比如说狗和狼都属于
?
??
??
??
??
??
?犬科,那么这个犬科就是抽象的,它具有狗和狼的共性,但是它很笼统。
?
??
??
??
??什么是抽象类?
?
??
??
??
??
??
?Java中可以定义没有方法体的方法,该方法的具体实现由子类完成,该方法称为抽象方法,
?
??
??
??
??
??
?包含抽象方法的类就是抽象类。
?
??
??
??
??
??
?举个例子: 比方说父亲要教两个孩子一个运动的功能,但是具体的是什么不教,两个孩子
?
??
??
??
??
??
?从父亲那继承过来后,就要重写这个运动功能,一个孩子踢足球,一个孩子打篮球,那么
?
??
??
??
??
??
?这个父亲就是抽象类,因为他将两个孩子的共性抽取出来了,并且孩子从父亲那继承过来
?
??
??
??
??
??
?之后还必须自己重写这个功能,不然孩子也是抽象类了。
?
?
??
??
??
??
??
?当多个类中出现相同功能,但是功能主体不同,这是可以进行向上抽取。这时,只抽取功能
?
??
??
??
??
??
?定义,而不抽取功能主体。
?
?
??
??
??
??
??
?部分代码:
?
??
??
??
??
??
??
?abstract class Fu//抽象类必须用abstract修饰,它不能new对象,比方说你new ?
??
??
??
??
??
???
??
???
?
??
??
??
??
??
??
?{ ?
??
??
??
??
??
??
??// 了一个对象调用相面这个方法有意义吗?
?
??
??
??
??
??
??
??
??
?abstract void sport();//抽象函数也必须用abstract修饰
?
??
??
??
??
??
??
?}
?
??
??
??
??
??
??
?class Zi1
?
??
??
??
??
??
??
?{
?
??
??
??
??
??
??
??
??
?void sport()//要使用父类的抽象方法必须复写抽象方法
?
??
??
??
??
??
??
??
??
?{
?
??
??
??
??
??
??
??
??
??
??
?System.out.println("踢足球");
?
??
??
??
??
??
??
??
??
?}
?
??
??
??
??
??
??
?}
?
??
??
??
??
??
??
?class Zi2
?
??
??
??
??
??
??
?{
?
??
??
??
??
??
??
??
??
?void sport()
?
??
??
??
??
??
??
??
??
?{
?
??
??
??
??
??
??
??
??
??
??
?System.out.println("打篮球");
?
??
??
??
??
??
??
??
??
?}
?
??
??
??
??
??
??
?}
-------------------------------------------------------------------------------------------------
?
??
??
??
??抽象类的特点:
?
??
??
??
??
??
??
?1,抽象方法一定在抽象类中。
?
??
??
??
??
??
??
?2.抽象方法只有方法声明,没有方法体,定义在抽象类中。
?
??
??
??
??
??
??
??
??格式:修饰符abstract 返回值类型 ?函数名(参数列表) ;
?
??
??
??
??
??
??
?3.抽象方法和抽象类都必须被abstract关键字修饰。
?
??
??
??
??
??
??
?4.抽象类不可以用new创建对象。因为调用抽象方法没意义。
?
??
??
??
??
??
??
?5.抽象类中的抽象方法要被使用,必须由子类复写起所有的抽象方法后,建立子类对
?
??
??
??
??
??
??
??
??象调用。如果子类只覆盖了部分抽象方法,那么该子类还是一个抽象类。
-------------------------------------------------------------------------------------------------
?
??
??
??
??
?抽象类与一般类没什么太大的区别,就是抽象类中比一般类多了个抽象方法,其他的
?
??
??
??
??
?还该怎么写该怎么写,抽象类中可以有好多函数,但并不意味着抽象类里面的函数都得是
?
??
??
??
??
?抽象的。另一个就是抽象类不能被实例化。
?
??
??
??
??
?抽象类中可以不定义抽象方法,加abstract的目的仅仅是不让创建该类的对象(不常见)。
?
?
??
??
??
??
?abstract 与final修饰的类的区别:
?
??
??
??
??
?用final修饰的类不能被继承,而用abstract修饰的类
一定要有子类,不然里面的抽象
?
??
??
??
??
?方法没人复写留着有什么用。
-------------------------------------------------------------------------------------------------
?
??
??
??
??
?abstract 与下面三个关键字不能共存:
?
??
??
??
??
??
??final:被final修饰的类不能有子类,而被abstract修饰的类一定是一个父类。
?
??
??
??
??
??
??private: 抽象类被私有了,不被子类所知,就无法被复写,而抽象方法出现的就是
?
??
??
??
??
??
??
??
??
??
??
?需要被复写。
?
??
??
??
??
??
??static:如果static修饰了抽象方法,那么连对象都省了,直接类名调用就可以了,
?
??
??
??
??
??
??
??
??
??
??可是抽象方法运行没意义。
-------------------------------------------------------------------------------------------------
?
?
??
??
??
??抽象类和接口中是否有构造函数?
?
??
??
??
??
??
?抽象类中有,抽象类是一个父类,而子类继承父类的时候,子类的构造函数第一句一定是
?
??
??
??
??
??
?父类的构造函数(super()),如果抽象类中没有,构造函数那子类不能实例化成功;
?
??
??
??
??
??
?接口中没有构造函数,因为接口中都是方法都是抽象的,变量都是被final修饰的不能更
?
??
??
??
??
??
?改的,而构造函数中可以有方法体,这与抽象函数相违背。然后类可以实现多个接口,若
?
??
??
??
??
??
?多个接口都有自己的
构造器,则不好决定子类的构造函数第一行怎么写。
-------------------------------------------------------------------------------------------------
?
??
??9. 模板方法模式
?
??
??
??
??什么是模版方法呢?
?
??
??
??
??
??
?在定义功能时,功能的一部分是确定的,但是有一部分是不确定,而确定的部分在使用不
?
??
??
??
??
??
?确定的部分,那么这时就将不确定的部分暴露出去。由该类的子类去完成。
?
??
??
??
??部分代码:
?
??
??
??
??
??
abstract class GetTime//1.例如获取一个for循环遍历运行的时间
{
public final void getTime()//2.获取时间的方法是确定的定义开始时间在定义结束时间
{
long start = System.currentTimeMillis();
//3.但是求那种for循环的代码是不确定的,比如说你是求打印100个数用的时间呢还是求遍
//历出数组中最大值然后再打印的时间呢
runcode();//4.所以求那段代码运行的时间是不确定的
long end = System.currentTimeMillis();
System.out.println("毫秒:"+(end-start));
}
public abstract void runcode();//5.所以把这段不确定的给暴露出去,让子类继承
}
class SubTime extends GetTime//
{
public void runcode()//6.然后子类需要求谁的运行时间就复写5的功能把谁写进去
{
for(int x=0; x<4000; x++)
{
System.out.print(x);
}
}
}
class TemplateDemo
{
public static void main(String[] args)
{
SubTime gt = new SubTime();//创建子类对象
gt.getTime();
}
}
??
?
?
??
??
?10.接口
?
??
??
??
??
?什么是接口?
?
??
??
??
??
??
?接口:可以认为是一个特殊的抽象类当抽象类中的方法都是抽象的,那么该类可以通过接
?
??
??
??
??
??
?口的形式来表示。用interface用来定义接口。格式为 : ?interface 接口名 {}
?
?
??
??
??
??
??
?接口中常见定义的有常量和抽象函数
他们的默认表达方式为:
?
??
??
??
??
??
??
??
?常量:public static final
?
??
??
??
??
??
??
??
?方法:public abstract?
?
??
??
??
??
??
??
??
?接口中的成员都是public修饰。
?
?
??
??
??
??接口是不可以创建对象的,因为有抽象方法。需要被子类实现,子类对接口中的抽象方法全都
?
??
??
??
??覆盖后,子类才可以实例化。否则子类是一个抽象类。
-------------------------------------------------------------------------------------------------
?
??
??
??
??
?接口的特点:
?
??
??
??
??
??
?1.对外暴露规则
?
??
??
??
??
??
?2.降低耦合度 ?
??需要举例,如usb。pci,主板。插座。
?
??
??
??
??
??
?3.接口是程序的功能扩展
?
??
??
??
??
??
?4.接口直接可以用来多实现
?
??
??
??
??
??
?5.类与接口之间是实现关系,而且类继承 ?类的同时可以多实现接口
?
??
??
??
??
??
?6.接口与接口之间有继承关系,并且可以多继承。
?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
???
?
??
??
??注意:java中不支持多继承类但是可以多实现接口,另外接口继承接口,接口之间存在多继承,
?
??
??
??
??
??
??类继承类的同时还能实现多个接口来进行功能扩展。
?
?
??
??
??
??
?接口与接口之间存在多继承,类之间不能多继承的原因是,如果两个父类中有两个相同的函数,
?
??
??
??
??
?方法体却不一样时,子类继承过来后,不知道该调用那个函数。而接口中因为都是抽象的方法,
?
??
??
??
??
?没有方法主体,所以接口之间可以继承。
-------------------------------------------------------------------------------------------------
?
??
??
??
?部分代码:
?
??
??
??
??
?
interface A
{
void methodA();
}
interface B
{
void methodB();
void methodD();//类可以多实现的原因,B和D中都有methodD(),类D显现哪个都一样
}
interface C //extends B,A接口之间可以多继承
{
void methodC();
void methodD();
}
class D implements B,C//类可以多实现接口
{
public void methodA(){}//因为接口中成员都是public权限的,所以子类要想用的话
public void methodC(){}//权限得大于等于public
public void methodB(){}
}
?--------------------------------------------------------------------------------------------------------------------------------------------------------------
2.多态
?
??
?1.什么是多态?
?
??
??
??
??
?多态:可以理解为事物存在的多种体现形态。
?
??
??
??
??部分代码:
?
??
??
??
??
??
?
abstract class Animal
{
abstract void eat();
}
class Cat extends Animal//1.使用多态前提是类与类(接口)之间必须具有继承或实现关系
{ //因为若没有继承关系2中Animal就不能接收它
public void eat()
{
System.out.println("吃鱼");//3.通常还要有覆盖关系
}
public void catchMouse()//子类特有的方法
{
System.out.println("抓老鼠");
}
}
class Dog extends Animal
{
public void eat()
{
System.out.println("吃骨头");
}
public void kanJia()//子类特有的方法
{
System.out.println("看家");
}
}
class DuoTaiDemo
{
public static void main(String[] args)
{
function(new Dog());//相当于Animal a = new Dog();
function(new Cat());//相当于Animal a = new Cat();
}
public static void function(Animal a)//2.而使用Animal可以接收所有它的子类
{
a.eat();//4.如果没有覆盖关系,把它接收过来又有什么用呢
}
}
??
??
?3.多态--转型
?
??
??
??
?上面代码是通过多态使用父类中的方法。因为子类中都复写了,所以可以通过把父类当参数传
?
??
??
??
?进来,然后接收它的子类,再调用父类的方法(其实就是子类的方法因为复写)就行了。
-------------------------------------------------------------------------------------------------
?
??
??
??
?但是怎么通过多态来调用子类中特有的方法呢? ?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
?
??
??
??
??
??
?Animal a = new Cat();接收一个猫类型的话,猫类型提升,向上转型就像byte提升为int ??
?
??
??
??
??
??
??
??
?如果想要调用猫的特有方法时,如何操作? ?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
?
??
??
??
??
??
??
??
??强制将父类的引用。转成子类类型。向下转型。 ?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
?
??
??
??
??
??
??
??
??
?Cat c = (Cat)a; ?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
???
?
??
??
??
??
??
??
??
??
??c.catchMouse(); ?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
?
??
??
??
??
??
??
?千万不要出现这样的操作,就是将父类对象转成子类类型。如下: ?
??
??
??
??
??
??
??
??
??
?
??
??
??
??
??
??
??
??
??
?Animal a = new Animal(); ?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
???
?
??
??
??
??
??
??
??
??
??
?Cat c = (Cat)a; ?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
?
??
??
??
??我们能转换的是父类应用指向了自己的子类对象时,该应用可以被提升,也可以被强制转换。 ?
???
?
??
??
??
??多态自始至终都是子类对象在做着变化。 ?
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
??
-------------------------------------------------------------------------------------------------
?
???
?
??
??
?如上面的代码:
?
??
??
??
??Animal a = new cat();//类型提升 向上转型了
?
??
??
??
??但是如和访问cat类中特有的方法呢?
?
??
??
??
??这个时候如果使用a.catchMouse();因为a被提升为动物类型了,那动物有很多种,不一定指的就是猫
?
??
??
??
?instanceof : 用于判断对象的类型。 对象 intanceof 类型(类类型 接口类型)?
?
?
?
??
??
??
??
??1,多态的体现
?
??
??
??
??
??
??
??父类的引用指向了自己的子类对象。例如:动物 x = new 猫();?
?
??
??
??
??
??2,多态的前提
?
??
??
??
??
??
??
??必须是类与类之间有关系。要么继承,要么实现。通常还有一个前提:存在覆盖。 ?
?
??
??
??
??
??3,多态的好处
?
??
??
??
??
??
??
??
?多态的出现大大的提高程序的
扩展性。
?
??
??
??
??
??4,多态的弊端:
?
??
??
??
??
??
??
??提高了扩展性,但是只能使用父类的引用访问父类中的成员。
?
??
??
??
??
??5,多态的应用
-----------------------------------------------------------------------------------
?
??
??4.多态中成员的特点
?
??
??
??
??多态中成员函数的特点:编译看左边运行看右边?
?
??
??
??
??成员变量的特点:无论编译还是运行都看左边?
?
??
??
??
??静态成员函数的特点:编译或运行都看左边?
-----------------------------------------------------------------------------------
?
??
??
??
??部分代码:
?
??
??
??
?
class Fu
{
int num = 5;
void show1()
{
System.out.println("Fu show_1");
}
void show2()
{
System.out.println("Fu show_2");
}
static void show4()
{
System.out.println("Fu show_4");
}
}
class Zi extends Fu
{
int num = 8;
int x=3;
void show1()
{
System.out.println("Zi show_1");
}
void show3()
{
System.out.println("Zi show_3");
}
static void show4()
{
System.out.println("Zi show_4");
}
static void show5()
{
System.out.println("Zi show_5");
}
}
class DuoTaiTeDian
{
public static void main(String[] args)
{
Fu f = new Zi();
//如果是f.Show3();则编译不通过因为父类中没有f.Show3();运行结果则是累类中的"Zi show_1";
f.show1();
//如果是f.x则编译不通过,因为看左边父类中无X成员变量,运行结果也是5,因为运行也看左边父类中有num=5;
System.out.println(f.num);
//因为左边父类中无show5(),所以编译不通过。如果为f.show4(),则打印结果为"Fu show_4";
f.show4();
}
}
??
??
?5.object类equal
?
??
??
??
??
?Object:是所有对象的直接后者间接父类,传说中的上帝。所以该类中定义的肯定是所有对象都
?
??
??
??
??
??
??
??
??具备的功能。
?
??
??
??
??
?Object类中已经提供了对对象是否相同的比较方法。如果自定义类中也有比较相同的功能,没
?
??
??
??
??
?有必要重新定义。只要沿袭父类中的功能,建立自己特有比较内容即可。这就是覆盖。
?
??
?
??
??
??
??
?使用运算符"=="与equals()方法都可以进行对象的比较但是两者是有区别的?
?
??
??
??
??
??
??
?当使用关系运算符"=="比较两个对象时,是比较两个对象使用的内存地址和内容是否像相同,
?
??
??
??
??
??
?如果两个对象使用的是同一个内存地址,并且内容相同,则结果返回true,否则结果为false。?
?
??
??
??
??
??
??
?当使用equals()方法比较两个对象时,则是比较两个对象的内容是否相同,而与内存地址无关,
?
??
??
??
??
??
?如果两个对象的内容相同,则结果为true,否则结果为false。
?
??
??
??
?部分代码:
?
??
??
??
??
class EqualDemo
{
public static void main(String[] args)
{
String str1 = new String("hello");
String str2 = new String("hell0");
String str3 = str2;
//用“==”比较str1与str2
System.out.println("str1与str2的比较结果为:"+(str1==str2));
//用“==”比较str2与str3
System.out.println("str1与str2的比较结果为:"+(str2==str3));
//用equals方法比较str1与str2
System.out.println("str1与str2的比较结果为:"+str1.equals(str2));
//用equals方法比较str2与str3
System.out.println("str1与str2的比较结果为:"+str2.equals(str3));
}
}
?
----------------------?android开发、java培训、期待与您交流! ----------------------