------- android培训、java培训、java博客、java学习型技术博客、期待与您交流! ----------
抽象类 abstract
概念:有抽象方法的类叫做抽象类
抽象类的特点 :
1.抽象方法一定在抽象类中。
2.抽象方法和抽象类都必须被abstract关键字修饰。
3.抽象类不可以用new创建对象。因为调用抽象方法没意义。
4.抽象类中的方法要被使用,必须由子类覆写其所有的抽象方法后,建立子类对象调用。
如果子类只覆盖了部分抽象方法,那么该子类还是一个抽象类。
对抽象类的应用:
假如我们在开发一个系统时需要对员工进行建模,员工包含3个属性:
姓名、工号、以及工资。经理也是员工,除了含有员工的属性外,另外还有一个奖金属性。
请使用继承的思想设计出员工类和经理类。要求类中提供必要的方法进行属性访问。
abstractclass Employee{
private Stringname;//被private修饰,范围只能在本类中访问,所以必须在此类中进行初始化
private Stringid;
privatedouble pay;
Employee(String name,String id,double pay){
this.name=name;
this.id=id;
this.pay=pay;
}
publicabstract void work();
}
//经理类
class Managerextends Employee{
privateint bonus;
Manager(String name,String id,double pay,int bonus){
super(name,id,pay);//子类中构造函数初始化方式,即访问父类构造函数(必须)
this.bonus=bonus;
}
publicvoid work(){//实现父类中的抽象方法
System.out.println("我是经理职责");
}
}
//员工类
class Proextends Employee{
Pro(String name,String id,double pay){
super(name,id,pay);
}
publicvoid work(){
System.out.println("普通员工职责");
}
}
模板方法设计模式--抽象类应用
需求:获取一段程序运行的时间。
原理:获取程序开始和结束的时间并相减即可。
获取时间:System.currentTimeMillis();
这种方式------>模板方法设计模式
什么是模板方法?
在定义功能时,功能的一部分是确定的,但是有一部分是不确定的,而确定的部分在使用不确定的部分。
那么这时就将不确定的部分暴露出去。由该类的子类去完成。
abstractclass GetTime{
publicfinal void getTime(){//final修饰后此方法不可以被覆写(确定部分)
long start=System.currentTimeMillis();
runCode();
long end=System.currentTimeMillis();
System.out.println("毫秒:"+(end-start));
}
publicabstract void runCode();//(不确定部分)留给子类去实现此抽象方法
}
class SubTimeextends GetTime{//要用来测试的程序
publicvoid runCode(){
for(int x=0;x<2000;x++){
System.out.println(x);
}
}
}
publicclass DateDemo {
publicstatic void main(String[] args) {
SubTime st=new SubTime();
st.getTime();
}
}
5、接口 interface
/*接口:初期理解可以认为是一个特殊的抽象类。
* 当抽象类中的方法都是抽象的时,那么该类可以通过接口的形式来表示。
* class用于定义类
* interface用于定义接口
* 接口定义时,格式特点:
* 1、接口中常见定义:常量、抽象方法
* 2、常量:public static final
* 3、方法:public abstract
* 接口中的成员都是public的。
* 接口:是不可以创建对象的,因为有抽象方法。
* 需要被子类实现,子类对接口中的抽象方法全都覆盖后,子类才可以实例化。
* 否则子类是抽象类。
* */
interface Inter{
publicstatic finalint NUM=3; //最终变量,不可以重新赋值
publicabstract void show();
}
class Test1implements Inter{
publicvoid show(){}//实现
}
publicclass InterfaceDemo {
publicstatic void main(String[] args) {
Test1 t=new Test1();
System.out.println(t.NUM);
System.out.println(Test1.NUM);
System.out.println(Inter.NUM);
}
}
接口的特点:
1.接口是对外暴露的规则。
2.接口是程序的功能扩展。
3.接口可以用来多实现。
4.类与接口之间是实现关系,而且类可以继承一个类的同时实现多个接口。
5.接口与接口之间可以有继承关系。
8.1多态
定义:某一类事物的多种存在形态。
例:动物中的猫,狗。
l 猫这个对象对应的类型是猫类型
猫 x=new 猫();
l 同时猫也是动物的一种,也可以把猫称为动物。
动物 y=new 猫();
动物是猫和狗具体事物中抽取出来的父类型。
父类型引用指向子类对象。
多态的体现
父类的引用指向了自己的子类对象。
父类的引用也可以接收自己的子类对象
1、多态的前提
必须是类与类之间有关系。要么继承,要么实现。
通常还有一个前提:存在覆盖。
2、多态的好处
多态的出现大大的提高程序的扩展性。
3、多态的弊端
提高了扩展性,但是只能使用父类的引用访问父类中的成员。
4、多态的应用
代码体现形式:
abstractclass Animal{
publicabstract void eat();//不确定的事物,提取出来
}
class Catextends Animal{
publicvoid eat(){
System.out.println("吃鱼");
}
publicvoid catchMouse(){
System.out.println("抓老鼠");
}
}
class Dogextends Animal{
publicvoid eat(){
System.out.println("吃骨头");
}
publicvoid houseKeeping(){
System.out.println("看家");
}
}
publicclass Polymorphic {
publicstatic void main(String[] args) {
function(new Dog());
function(new Cat());
}
publicstatic void function(Animal c){//提高了扩展性
c.eat();//只能使用父类的引用访问父类中的成员(反例动物不一定都会抓老鼠)
}
}
结果:吃骨头,吃鱼
publicclass Polymorphic2 {
publicstatic void main(String[] args) {
Animal a=new Cat();//类型提升。向上转型。
A.eat();
//如果想要调用猫的特有方法时,如何操作?
//强制将父类的引用,转成子类类型。向下转型
Cat c=(Cat)a;
c.catchMouse();
}
结果:吃鱼;抓老鼠
publicstatic void function(Animal a){
a.eat();
if(ainstanceof Cat){
Catc=(Cat)a;
c.catchMouse();
}elseif(a instanceof Dog){
Dogd=(Dog)a;
d.houseKeeping();
}
}
instanceof :它的作用是测试它左边的对象是否是它右边的类的实例,返回boolean类型的数据
结果:吃骨头
看家
吃鱼
抓老鼠
分析:Animal a=new Animal();
Cat c=(Cat)a;
分析中的操作是错误的,将父类对象转成子类类型。
我们能转换的是父类应用指向了自己的子类对象时,该应用可以被提升,也可以被强制转换。
多态自始自终都是子类对象在做着变化。
5、在多态中成员函数的特点:(非静态)
在编译时期:参阅引用型变量所属的类中是否有调用的方法。如果有,编译通过,如果没有编译失败。
在运行时期:参阅对象所属的类中是否有调用的方法。(父类中方法也是子类的方法)。
简单总结就是:成员函数在多态调用时,编译看左边,运行看右边。
代码:
class Fu{
void method(){
System.out.println("Fu——1");
}
void method2(){
System.out.println("Fu——2");
}
}
class Ziextends Fu{
void method(){
System.out.println("Zi——1");
}
void method3(){
System.out.println("Zi——3");
}
}
publicclass TestExtends {
publicstatic void main(String[] args) {
Fu z=new Zi();
z.method();z.method2();//z.method3();
}
}
6、在多太中,成员变量的特点:(面试)
当子类和父类出现同名的变量时,内存中出现了两个同名变量,一个是父类的一个是子类的。
多态情况下:
无论编译和运行,都参考左边(引用型变量所属的类)。
代码:
class Fu{
intnum=8;
}
class Ziextends Fu{
intnum=9;
}
publicclass TestExtends {
publicstatic void main(String[] args) {
Fu f=new Zi();//多态中输出父类的内容,不可覆盖
System.out.println(f.num);
Zi z=new Zi(); //非多态中可以覆盖
System.out.println(z.num);
}
}
结果:8,9
7、在多态中,静态成员函数的特点:
无论编译和运行,都参考左边
代码:
class Fu{
staticvoid method(){
System.out.println("Fu——1");
}
}
class Ziextends Fu{
staticvoid method(){
System.out.println("Zi——1");
}
}
publicclass TestExtends {
publicstatic void main(String[] args) {
Fu z=new Zi();//多态中
z.method();
}
}
结果:Fu——1
面向对象的扩展--数据库操作。
1、链接数据库
2、操作数据库,增C 、删D 、改 U、查R
C create R read U update D delect
3、关闭数据库链接。
情景描述:开始是通过JDBC来操作数据库,可是5年后需求使用Hibernate操作数据库,而又不想更改原来的操作数据库的代码,那么,我们此时可以定义一个有相同同能的接口即可:
interface UserInfoDAO{
publicvoid add(user);
publicvoid delete(user);
}
class UserInfoByJDBCimplements UserInfoDAO{
publicvoid add(User user)
{
1、链接数据库;
2、使用sql语句添加数据。;
3、关闭链接;
}
publicvoid delete(User user)
{
1、链接数据库;
2、使用sql语句添加数据。;
3、关闭链接;
}
}
class UserInfoByHibernateimplements UserInfoDAO{
publicvoid add(User user)
{
1、链接数据库;
2、使用sql语句添加数据。;
3、关闭链接;
}
publicvoid delete(User user)
{
1、链接数据库;
2、使用sql语句添加数据。;
3、关闭链接;
}
}
publicclass test{
publicstatic voidmain(String[] args){
//开始很麻烦的实现方式
/*
UserInfoByJDBC u=newUserInfoByJDBC();
u.add(user);
u.add(user);
UserInfoByHibernate u=newUserInfoByHibernate();
u.add(user);
u.add(user);
*/
//5年后的成果:父类接口指向子类对象 =newUserInfoByHibernate();
UserInfoDAO u=new UserInfoByJDBC();//多态的体现,降低程序之间的耦合性
u.add(user);
u.add(user);
}
}
vObject类中的方法
v 面向对象(Object类-equals())
Object:是所有对象的直接或者间接父类。
该类中定义的肯定是所有对象都具备的功能。
深入理解equals():
其实父类的equals方法比较的是两个对象的地址值是否相等,在没覆写的情况下,
Demo2 d1=new Demo2(3);
Demo2 d2=new Demo2(3);
System.out.println(d1.equals(d2));
//返回的结果是false,因为两个对象的地址值是不相等的
当我们覆写父类的equals方法后让其比较的是对象中num变量的值是否相等;
Demo2 d1=new Demo2(3);
Demo2 d2=new Demo2(3);
System.out.println(d1.equals(d2));
//同样情况下返回的结果是true,因为两个对象中的num值3==3
代码体现:
class Demo2{
privateint num;
Demo2(int num){
this.num=num;
}
publicboolean equals(Object obj){//覆写父类Object的方法
if(!(objinstanceof Demo2))//关键字
returnfalse;
Demo2 d=(Demo2)obj;//向下转型,多态
returnthis.num==d.num;
}
}
publicclass ObjectDemo {
publicstatic void main(String[] args) {
Demo2 d1=new Demo2(3);
Demo2 d2=new Demo2(4);
System.out.println(d1.equals(d2));//两个对象的比较,比的值是地址值;结果false
}
}
v 面向对象(Object类-toString())
toString():你创建的每个类都会继承该方法。它返回对象的一个String表示,并且对于调试非常有帮助。然而对于默认的toString()方法往往不能满足需求,需要覆盖这个方法。
class Person_0{
private Stringname;
Person_0(Stringname){
this.name=name;
}
@Override
public String toString(){//覆盖
return"我的名字是:"+name;
}
}
publicclass ToStringDemo {
publicstatic void main(String[] args){
Person_0 p=new Person_0("king");
System.out.println(p.toString());
}
}
9.1内部类的访问规则:
1、内部类可以直接访问外部类中的成员,包括私有。
之所以可以直接访问外部类中的成员,是因为内部类中持有了一个外部类的引用(默认省略)。
格式:外部类名.this
2、外部类要访问内部类,必须建立内部类对象。
访问格式:
1、当内部类定义在外部类的成员位置上,而且非私有,可以在外部其它类中直接建立内部类对象。
格式:外部类名.内部类名 变量名=外部类对象.内部类对象;
2、当内部类在成员位置上,就可以被成员修饰符所修饰。
比如,private:将内部类在外部类中进行封装。
Static :内部类就具备static的特性。
当内部类被static修饰后,只能直接访问外部类中的static成员,出现了访问局限。
在外部其它类中,如何直接访问static内部类的非静态成员呢?
new Outer.Inner().function();
在外部其它类中,如何直接访问static内部类的静态成员呢?
Outer.Inner.function();
注意:当内部类中定义了静态成员,该内部类必须是static的。
当外部类中的静态方法访问内部类时,内部类也必须是静态的。
代码:
class Outer{
privateint num=9;
class Innter{//内部类在外部类的成员位置,可以对其进行私有化,private;
//则就不能直接的访问内部类的成员了。
publicvoid show(){
System.out.println("inner:"+num);//之所以能直接访问外部成员原因:
//此处省略了Outer.this;//其实是Outer.this.num;
}
}
void method(){
Innter in=new Innter();
in.show();
}
}
publicclass ToStringDemo {
publicstatic void main(String[] args){
//外部类间接访问内部类成员
Outer o=new Outer();
o.method();
//直接访问内部类中的成员
Outer.Innter oi=new Outer().new Innter();
oi.show();
}
}
内部类与外部类的由来:
当描述事物时,事物的内部还有事物,该事物用内部类来描述。
因为内部事物在使用外部事物的内容。
内部类就是能直接访问外部类成员的一个描述。
class Body{
private class xinZang{
}
public void show(){
new xinZang();
}
}
9.2内部类定义在局部时
1、不可以被成员修饰符修饰,如不可以被static修饰
2、可以直接访问外部类中的成员,因为持有外部类中的引用。
但是不可以访问它所在的局部中的变量。只能访问被final修饰的局部变量。
class Outer2{
intx=3;
void method(finalint a){
finalint y=4;
class Inner{//局部内部类只能访问被final修饰的局部变量
void function(){
System.out.println(x);
System.out.println(y+"::"+a);
}
}
new Inner().function();//对内部类中函数的访问
}
}
publicclass InnerClass {
publicstatic void main(String[] args) {
new Outer2().method(5);
new Outer2().method(6);
}
}
//a被final修饰为什么可以为a传两次值呢?
//因为a是局部变量a在栈内存,把5赋给a,此时a的值被锁定为5,当第一句话执行完,出栈就释放了;
//再调用的话又是一次进栈..
9.3匿名内部类
1、匿名内部类其实就是内部类的简写格式。
2、定义匿名内部类的前提:
内部类必须是继承一个类或者实现接口。
3、匿名内部类的格式:new父类或者接口(){定义子类的内容};
4、其实匿名内部类就是一个匿名子类对象。而且这个对象有点胖。可以理解为带内容的对象。
5、匿名内部类中定义的方法最好不用超过三个;
abstractclass AbsDemo{
abstractvoid show();
}
class Outer_1{
intx=3;
class Innerextends AbsDemo{
void show(){
System.out.println("show:"+x);
}
}
publicvoid function(){
new Inner().show();
}
}
//===演变如下===============
class Outer_2{
intx=3;
publicvoid function(){
//new Inner().show();
new AbsDemo(){
void show(){
System.out.println("show:"+x);
}
}.show();
}
}
publicclass NoNameClass {
publicstatic void main(String[] args) {
new Outer_2().function();
}
}
//===多态===============
classOuter_3{
intx=3;
publicvoid function(){
AbsDemo a=new AbsDemo(){//父类引用指向之类对象--多态
void show(){
System.out.println("show:"+x);
}
voidmethod(){
System.out.println("hello");
}
};
a.show();
//a.method();看左边,父类中未定义,编译失败;如果编译通过则运行输出右边内容
}
}
匿名内部类----接口
interface Inter2{
void method();
}
class Test2{
//补充代码,通过匿名内部类。
/* static classInner implements Inter2{
public voidmethod(){
System.out.println("methodrun");
}
}*/
static Inter2 function(){
returnnew Inter2(){
publicvoid method(){
System.out.println("methodrun");
}
};
}
}
publicclass InnerClassTest {
publicstatic void main(String[] args) {
//Test2.function():Test2类中有一个静态方法function。
//.method():function()这个方法运算后的结果是一个对象。而且是一个inter2类型的对象
//因为只有inter2类型的对象,才可以调用method方法。
Test2.function().method();
}
}
面试题:在既没有抽象类又没有接口的情况下还能创建匿名内部类吗?
class Outerdemo{
publicstatic void getFun(){
new Object(){//此处不能用对象接收,因为父类Object方法中没有我们自己定义的函数,编译会失败,调用的话只能最后面.fun();
publicvoid fun(){
System.out.println("调用了");
}
}.fun();
}
}
------- android培训、java培训、java博客、java学习型技术博客、期待与您交流! ----------
如有疑问:http://edu.csdn.net/