------- android培训、java培训、期待与您交流! ----------
把这部分单独拿出来说,是因为个人认为这部分在面向对象中是很重要的组成,需要掌握。
1:继承
classA
{
publicvoid show()
{
sop("hello");
}
}
classB
{
publicvoid show()
{
sop("hello");
}
}
观察上面两个类,发现类中的代码一致。那么,如果这样的类比较多的话,就会产生代码重复。
为了减少这种重复,我们就这样思考:我们首先定义一个类,让这个类具备所有共同的内容,在
定义其他类的时候,与这个类产生一个关系,就可以直接具备这些功能。可以,这就是java中的继承。
代码:
classC
{
publicvoid show()
{
sop("hello");
}
}
classA extends C{}
classB extends C{}
继承的好处:
A:提高了代码的复用性。
B:让类与类产生了关系,是多态的前提。
Java中继承特点:
A:Java是单继承的
B:Java可以多层继承
继续看:
classA
{
publicvoid show()
{
sop("helloA");
}
}
classB
{
publicvoid show()
{
sop("helloB");
}
}
观察上面的代码,发现,方法声明相同,方法体不同。
但是呢,我们也可以向上抽取共性内容。
//如果一个类中有abstract修饰的方法,类必须是抽象类,也就是说类必须用abstract修饰
abstractclass C
{
//没有方法体的方法要用abstract修饰
publicabstract void show();
}
classA extends C
{
publicvoid show()
{
sop("helloA");
}
}
classB extends C
{
publicvoid show()
{
sop("helloB");
}
}
强制要求某个体系必须完成某些功能。但是这些功能在早期是不确定子类是怎么实现的。
抽象类的特点:
A:抽象类的成员特点
a:成员变量 可以是常量也可以是变量
b:成员方法 可以是抽象方法,也可以是非抽象方法
c:构造方法 有构造方法,但是不能创建对象。用于子类实例化使用。
B:abstract不能和哪些关键字共存
a:final
b:private
c:static
继续看:
abstractclass C
{
//没有方法体的方法要用abstract修饰
publicabstract void show();
}
classA extends C
{
publicvoid show()
{
sop("helloA");
}
}
classB extends C
{
publicvoid show()
{
sop("helloB");
}
}
如果一个体系抽取出来的内容在一个抽象类中的都是抽象的内容的时候,该抽象类就可以定义为一个接口。
接口的特点:
A:成员特点
成员变量 只有常量 默认修饰符 public staticfianl 但是建议自己手动给出。
成员方法 只有抽象方法 默认修饰符 public abstract但是建议自己手动给出。
构造方法 没有
2:抽象类与接口的区别
A:成员
抽象类:
成员变量 可以是常量也可以是变量
成员方法 可以是抽象方法,也可以是非抽象方法
构造方法 有构造方法,但是不能创建对象。用于子类实例化使用。
接口:
成员变量 只有常量 默认修饰符 public staticfianl 但是建议自己手动给出。
成员方法 只有抽象方法 默认修饰符 public abstract但是建议自己手动给出。
B:接口的出现避免了单继承的局限性
类与类的关系:
继承关系,单继承。但是可以多层继承。
类与接口的关系:
实现关系,单实现,也可以多实现。
类在继承一个类的同时还可以实现多个接口
接口与接口的关系:
继承关系,单继承,也可以多继承。
C:抽象类被继承体现的是:"isa"
抽象类里面定义的是一个体系的共性内容
接口被实现体现的是:"likea"
接口里面定义的是一个体系的扩展内容
D:篮球运动员,乒乓球运动员
篮球教练,乒乓球教练
为了出国交流,乒乓球人员需要学习英语。
请用所学知识分析整个描述有哪些类,抽象类,接口。
分析问题:从下往上。
解决问题:从上往下。
3:多态
A:对象在不同时刻表现出现的不同状态。
举例:
水(水蒸气,冰,水)
狗(动物,狗)
B:多态前提
a:要有继承或者实现关系
b:要有方法的重写
c:父类(接口)引用指向子类对象(代码体现)
C:代码体现:
classFu
{
intnum = 10;
publicvoid show()
{
System.out.println("showFu");
}
}
classZi extends Fu
{
intnum = 20;
//intnum2 = 20;
publicvoid show()
{
System.out.println("showZi");
}
}
//代码体现
Fuf = new Fu();
sop(f.num);//10
f.show();//show Fu
Zizi = new Zi();
sop(zi.num);//20
zi.show();//showZi
Fuf = new Zi();
sop(f.num);//10
f.show();//showzi
为什么呢(成员变量用的是Fu的,而成员方法用的是Zi的)?
成员方法存在着重写。
举例:孔子装爹。
孔子爹:教书() --JavaSE, age:40
孔子:教书() -- 论语, 玩游戏(), age:20
//多态体现
孔子爹 k爹 = new 孔子(); //孔子就穿上爹的衣服,带上爹的眼镜,沾上胡子。 向上转型
k爹.教书(); -- 论语
sop(k爹.age); -- 40
//k爹.玩游戏(); -- 不能调用。多态的弊端:不能使用子类的特殊方法。
//回家了
//孔子 k = new 孔子();
//k.玩游戏();
孔子 k = (孔子)k爹; //脱下爹的衣服,去除眼镜,去掉胡子 向下转型
k.教书(); -- 论语
sop(k.age);-- 20
//为什么要使用向下转型:就是为了使用子类的特殊功能
k.玩游戏();
D:多态的好处:
提高代码的扩展性及后期的维护性。
abstractclass Animal
{
publicabstract void eat();
}
classDog extends Animal
{
publicvoid eat()
{
sop("狗吃骨头");
}
}
classCat extends Animal
{
publicvoid eat()
{
sop("猫吃鱼");
}
}
classPig extends Animal
{
publicvoid eat()
{
sop("猪吃草");
}
}
classTest
{
publicstatic void main(String[] args)
{
Dogd = new Dog();
//d.eat();
//d.study();
//d.play();
//...
Dogd2 = new Dog();
//d2.eat();
//继续操作,假如要操作的内容特别多。
//代码的重复度变高。
//用功能改进
printDog(d);
printDog(d2);
Catc = new Cat();
Catc2 = new Cat();
printCat(c);
printCat(c2);
Pigp = new Pig();
Pigp2 = new Pig();
printPig(p);
printPig(p2);
//我后期还喜欢宠物狼,宠物虎,宠物蛇...
}
/*
publicstatic void printDog(Dog d)
{
d.eat();
//d.study();
//d.play();
//...
//很多操作
}
publicstatic void printCat(Cat c)
{
c.eat();
//c.study();
//c.play();
//...
//很多操作
}
publicstatic void printPig(Pig p)
{
p.eat();
//p.study();
//p.play();
//...
//很多操作
}
*/
publicstatic void printAnimal(Animal a)
{
a.eat();
//a.study();
//a.play();
//...
//很多操作
}
}
4.this 关键字
A:this关键字代表当前类的当前对象的引用
B
1将重名的成员变量和局部变量进行区分
2调用构造函数
this(); ----调用无参数
this(实参列表);-----调用带参数的
注意:this必须构造函数中的第一行
5.构造函数
A作用
对对象属性进行初始化,----对对象进行初始化
B特点
没有任何返回值
方法名必须和类名一至
每一个类型都有一个默认的无参数的构造函数(在没有显示的定义构造函数的时候,默认的才起作用)
由new关键调用
6.面试相关
A局部代码块
作用:提高内存的使用率
{
intx=10;
}
B构造代码块
作用:对所有的对象进行共同的初始化
{
this.属性=值
}
C构造代码块和构造函数的区别
对所有的对象进行共同的初始化,构造函数对对象进行特定的初始化
构造代码块先于构造函数执行
D一个对象的产生过程
1首先加载class文件
2如果定义的为匿名对象,不需要在栈内存开辟空间
如果定的有名字的对象,在占内存开辟空间
3在对象开辟空间保存对象
4先进行默认初始化
5显示初始化
6针对显示初始化首先:构造代码块初始化
7针对显示初始化首先:构造函数初始化
8将对象内存中对象的地址赋值给占内存中的变量