java知识点Word文件下载.docx
- 文档编号:18613797
- 上传时间:2022-12-29
- 格式:DOCX
- 页数:38
- 大小:40.02KB
java知识点Word文件下载.docx
《java知识点Word文件下载.docx》由会员分享,可在线阅读,更多相关《java知识点Word文件下载.docx(38页珍藏版)》请在冰豆网上搜索。
继承类和同一软件包的类可访问。
(3)如果构造方法为private,那么在其他类中不能创建该类的对象。
抽象类
(1)抽象类不能创建对象。
(2)如果一个类中一个方法为抽象方法,则这个类必须为abstract抽象类。
(3)继承抽象类的类在类中必须实现抽象类中的抽象方法。
(4)抽象类中可以有抽象方法,也可有非抽象方法。
抽象方法不能为private.
(5)间接继承抽象类的类可以不给出抽象方法的定义。
final关键字
(1)一个对象是常量,不代表不能转变对象的成员,仍可以其成员进行操作。
(2)常量在使用前必须赋值,但除了在声明的同时初始化外,就只能在构造方法中初始化。
(3)final修饰的方法不能被重置(在子类中不能出现同名方法)。
(4)如果声明一个类为final,则所有的方法均为final,无论其是否被final修饰,但数据成员可为final也可不是。
接口interface
(用implements来实现接口)
(1)接口中的所有数据均为static和final即静态常量。
尽管可以不用这两个关键字修饰,但必须给常量赋初值。
(2)接口中的方法均为public,在实现接口类中,实现方法必须可public关键字。
(3)如果使用public来修饰接口,则接口必须与文件名相同。
多重继承
(1)一个类继承了一个类和接口,那么必须将类写在前面,接口写在后面,接口之间用逗号分隔。
(2)接口之间可多重继承,注意使用关键字extends.
(3)一个类虽只实现了一个接口,但不仅要实现这个接口的所有方法,还要实现这个接口继承的接口的方法,接口中的所有方法均须在类中实现。
接口的嵌入
(1)接口嵌入类中,可以使用private修饰。
此时,接口只能在所在的类中实现,其他类不能访问。
(2)嵌入接口中的接口一定要为public.
类的嵌入
(1)类可以嵌入另一个类中,但不能嵌入接口中。
(2)在静态方法或其他方法中,不能直接创建内部类对象,需通过手段来取得。
手段有两种:
classA{classB{}BgetB(){Bb=newB();
returnb;
}}staticvoidm(){Aa=newA();
A.Bab=a.getB();
//或者是A.Bab=a.newB();
}
(3)一个类继承了另一个类的内部类,因为超类是内部类,而内部类的构造方法不能自动被调用,这样就需要在子类的构造方法中明确的调用超类的构造方法。
接上例:
classCextendsA.B{C(){newA()。
super();
//这一句就实现了对内部类构造方法的调用。
}}
构造方法也可这样写:
C(Aa){a.super();
}//使用这个构造方法创建对象,要写成Cc=newC(a);
a是A的对象。
在.NET发展史中,2.0是具有里程碑意义的一个版本。
在.NET2.0带来的诸多新特性中,我认为泛型是最重要的一个。
虽然泛型出现已有多年,连Java都早已借鉴引入了泛型(虽然是语法糖),可是用泛型的编程思维方式并没有得到相应的普及。
一方面是由于过去大量的Framework仍然是在非泛型时代写成的,另一方面泛型的设计模式没有得到发展,改变的时候该到了。
来举一个例子说明这两点。
我们如果写过网络数据抓取的代码,应该熟悉这样的代码:
1varrequest=WebRequest.Create("
asHttpWebRequest;
或者这么写,也是一样:
1varrequest=HttpWebRequest.Create("
大家可想过,为什么每次都要as一下?
类似的情况还有:
1varbm=Image.FromFile("
e:
\\me.jpg"
)asBitmap;
2varbm=Bitmap.FromFile("
我想过,但没想明白。
上面两种写法,都是调用父类的工厂方法,实际返回了一个子类的实例。
显然,即使不了解OCP,凭直觉也应该想到,父类的实现中不应该被子类所决定。
写WebRequest和Image的前辈可能也觉得直接返回子类实例不妥,所以阴险地把方法签名的返回类型改成了父类。
虽然这种行径值得严重鄙视。
但.NET程序员大都是人云亦云,照葫芦画瓢的好学生,所以这个问题多年了也没有修改。
理想的设计应该是这样:
父类的每个子类,都有独立的工厂方法,返回其自身的实例。
这样做法,在泛型出现前非常笨拙,得不偿失,但有了泛型,就可以精巧地实现。
以模拟Image类为例,Image和BitMap实现如下:
1classImage<
T>
whereT:
Image<
new()
2{
3publicstringPath{get;
set;
4publicstaticTFromFile(stringpath)
5{
6returnnewT(){Path=path};
7}
8}
9
10classBitmap:
Bitmap>
11{
12
13}
Image自身的工厂方法,就没有存在的必要了。
【大石头对X组件泛型基类的举例】泛型基类,类型自己作为泛型基类的泛型参数。
2006年我把我们的数据映射框架NewLife.XCode改为泛型基类的写法,两个月后取消了这种做法,因为实在是太诡异了。
另外,当时从网络上找到的资料,微软并不推荐这种写法,理由是会让代码变得异常晦涩难懂。
2007年,NewLife.XCode重新开始使用泛型基类,这回总算控制住了。
于是,我们的充血实体类基本都是:
User:
Entity<
User>
Log:
Log>
User和Log就“继承”了Entity<
>
里面静态方法FindAll,并且返回类型是List<
和List<
。
2009年,我们又这样玩:
User<
:
{//实体类主体}
{//默认实体}
User1:
User1>
{//第一种扩展,比如增加字段属性}
User2:
User2>
{//第二种扩展,比如增加业务逻辑}
XCode从v1.2起,就进入了第二代,关键点就在于泛型基类Entity<
TEntity>
的使用。
在第一代XCode中,因为充血模型,实体类上要附带大量的方法,而当它们的返回类型是实体类或者实体类集合时,这些方法就必须实现于实体类的代码中,实际上是通过代码生成器来生成。
在第二代XCode,引入了泛型基类技术,实体类通过泛型参数TEntity指定最终返回类型,编写查询方法的时候,返回类型使用泛型参数TEntity即可。
所以,第二代实体类只有属性和索引器,基本不需要生成查询和操作的方法,因为它们都在泛型基类里面实现了。
大多数情况下,实体类指定的基类泛型参数就是它自己,因为它需要以它自己作为返回类型。
但XCode开发模式是面向对象的,包括实体类,也希望能够继承,增加一些功能,该功能可以通过改变泛型参数来实现。
绑定子类的泛型基类,反模式?
“绑定子类的泛型层基类”,这个模式在一些著名的框架中也见到过,如果CSLA、BlogEngine。
我自己在原来的写的框架中,也用到过。
当然了,个人认为是反模式,各们同仁并不一定这样认为,仁者见仁,智者见智了。
不过我好几次都是受尽折磨,所以决定写出来给大家分享下心得。
“绑定子类的泛型层基类”用在某些地方,而不是用在任何地方.用在ORM上就非常合适.。
今天要说的主题正是基于LayerSupertype,并结合了泛型技术而实现的,同样,它还有一个重要的约定:
泛型的类型参数必须是最终的子类。
看如下一个例子:
1publicabstractclassEntityBase<
whereT:
EntityBase<
2{
3publicintId{get;
}
4//sthelseimportant......
5}
6publicclassUser:
7{
8publicstringName{get;
9}
10
11publicclassArticle:
Article>
12{
13publicstringTitle{get;
14}
EntityBase作为所有实体类的基类,提供了统一的实体模板、约定和一些通用的基础实现。
基于这个基类的代码重用,使得子类的代码非常简单。
这里和普通继承、普通泛型的不同点在于父类在运行时绑定了具体子类的类型。
带来的问题使用这种模式,缺点是显而易见的:
1.不能直接使用基类进行统一的处理
继续上面的例子,这样的设计,使得我们不能对所有的实体进行统一的处理。
由于User和Article的基类其实是两个不同的运行时类型,所以我不能把它们转换为同一个“实体”类型。
如:
EntityBasea=newArticle();
a=newUser();
我甚至都不可能用到抽象的EntityBase类,因为我要使用此类,必须指定具体的子类,但是我如果知道要使用哪个具体的子类,也就没有必要使用它们的基类了。
也就是说,根本就不存在实体的抽象类,而EntityBase<
存在的意义只是为了代码重用。
我不知道这是否能看为违反了OO的Liskov替换原则,不过真是难以忍受。
2.无法直接实现实体的再继承
第二个问题,同样是继承机制的问题。
我无法从现在的具体实体类直接进行派生!
!
我无法使用这样的语法:
GoodArticle:
Article。
这是因为Article已经“告诉”基类EntityBase<
绑定子类的类型是Article,而不是GoodArticle,这按照EntityBase<
设计时的约定“T必须是最终的子类”相矛盾!
无法继承……继承作为OO三大特性中的一个,这个问题简直无法忍受。
想办法绕开这两个问题
其实,上面提到的两个问题,在技术上都是能够找到一些方法来解决的:
1.无法向基类转换。
这个问题产生的原因,主要是因为没有一个“与子类无关的抽象”存在。
我们可以为EntityBase<
添加IEntity接口,这样,所有的子类都能转换为IEntity,也就能进行统一的处理。
2.无法再继承。
要解决这个问题,我们需要把需要进行再继承的类也提取为一个泛型基类和一个继承此基类的空的子类。
1publicclassArticle<
:
Article<
2{
3publicstringTitle{get;
4}
5
6publicclassArticle:
{}
7
8publicclassGoodArticle:
GoodArticle>
{}
这样的方案好像可以解决,但是这样的设计实在让人难以接受:
*作为设计类库来说,我只是添加了一个单向依赖父类的子类,却不得不修改父类的代码,分离为两个类。
*要不就是所有的类都直接写成一个泛型类+一个空子类的方法。
(这个设计丑陋吗?
)
*没有解决根本的问题:
TopArticle并不是一个Article,它只是一个和Article有重用代码的类。
【对上述疑问的理解】
1.对于一项语言特性,一定要有选择的用,要明白它的含义,知道把它放在哪里最合适,而不是一味的在任何地方都使用.
2.User和Article本就不是同一父类的子类,因为它们映射的是数据库中的表,表和表之间是没有继承关系的,只有外键关系;
这里的泛型约束就很好的阻止了开发人员为实体类指定派生类.也就是说,这是框架设计者有意为之.
3.泛型实现的是编译时(静态)多态,不是运行时多态,EntityBase<
和EntityBase<
其实是不同的两个静态类型,这是在编译器就决定了的,不用等到运行时.
EntityBase<
我们称为泛型模板,注意,有"
模板"
这个后缀,而EntityBase<
则称为泛型模板EntityBase<
的实例.
总结知识点的实例
[html]viewplaincopy
11abstractclassAnimal{
12publicabstractvoideat();
13}
14
15classCatextendsAnimal{
16publicvoideat(){
17System.out.println("
fish"
);
18}
19
20publicvoidcatchMouse(){
21System.out.println("
CatchMouse"
22}
23}
24
25classDogextendsAnimal{
26publicvoideat(){
27System.out.println("
bone"
28}
29
30publicvoidkanJia(){
31System.out.println("
KAanJia"
32}
33}
34
35classDuotaiDemo{
36publicstaticvoidman(String[]args){
37Animalc=newCat();
//多态的体现
38Animald=newDog();
39fun(newCat());
//多态的出现大大提高了程序的扩展性
40}
41
42publicstaticvoidfun(Animala)//提高了代码的复用性
43{
44a.eat();
45}
46}
多态的体现
父类的引用指向自己的子类对象,父类的引用也可以接收自己的子类对象
父类父类引用=new子类实例(Animalc=newCat())
多态的前提
必须是类与类之间必须有关系,要么继承,要么实现,并且存在覆盖
多态的转型
向上转型(自动完成)父类父类引用=new子类实例(Animalc=newCat())
向下转型(强制转换)子类子类引用=(子类)父类引用(Catc1=(cat)c)
能够进行向下转型的只能是子类进行向上转型的父类应用转换成原来的子类
*instanceof关键字
Instanceof是Java中的二运运算符,也是Java中的保留关键字,作用是测试左边的对象是否是右边类的实例
Catc=newCat();
If(cinstanceofCat)
System.out.println(“c是Cat的实例”);
*多态中非静态成员函数的特点:
在编译时期:
参阅父类中是否有调用的方法,如果有则编译通过,否则编译失败
在运行时期:
运行子类的方法
*多态中成员变量的特点
无论编译还是运行,都参考左边(引用变量所属的类)
47classFu{
48intx=5;
49
50publicstaticvoidmethod(){
51System.out.println("
Fumethod"
52}
53}
54
55classZiextendsFu{
56intx=8;
57
58publicstaticvoidmethod(){
59System.out.println("
Zimethod"
60}
61
62publicstaticvoidmain(String[]args){
63Fuz=newZi();
64System.out.println(z.x);
//结果为5
65Ziz1=newZi();
66System.out.println(z1.x);
//结果为8
67}
68}
*多态中静态成员函数的特点
publicstaticvoidmain(String[]args)
{
Fuzi=newZi();
zi.method();
//结果是Fumethod
Zizi=newZi();
//结果是Zimethod
多态的好处
多态的出现大大的提高了程序的扩展性。
多态的弊端
只能使用父类的引用访问父类中的成员,而不能访问子类所特有的成员。
接口与多态(第五章)中的关键知识点
继承
多态
1.3.1多态在代码中的体现
父类或者接口的引用指向其子类的对象。
对象的多态性:
动物x=new猫();
一个对象两种形态。
就是一个对象对应着不同类型。
一般简单来说就是父类型的对象指向子类型的引用。
注意:
对于转型,自始自终都是子类对象在做着类型的变化。
向上转型特点:
1,限制子类特有的功能。
2,提高扩展性。
1.3.2多态的好处:
应用程序不必为每一个子类编写功能调用,只需要对父类进行处理即可。
这一招叫"
以不变应万变"
,可以大大提高程序的可复用性。
子类的功能可以被父类的变量调用,这叫向后兼容,可以提高程序的可扩充性和可维护性。
现在写的程序可以调用将来写的程序不足为奇。
1.3.3多态的弊端
弊端:
前期定义的内容不能使用(调用)后期子类的特有内容
1.3.4多态使用的前提:
1,必须有关系,要么继承,要么实现。
2,要有覆盖。
1.3.6多态时成员的特点:
成员变量。
编译时:
参考引用型变量所属的类中是否有调用的成员变量,有,编译通过,没有,编译失败。
运行时:
参考引用类型变量所属的类中是否有调用的成员变量,并运行该所属类中的成员变量。
简单说:
编译和运行都参考等号的左边。
(一般开发里面少见)
示例代码:
classFu
{
intnum=1;
}
classZiextendsFu
intnum=9;
classDemo
publicstaticvoidmain(String[]args)
Fuf=newZi();
System.out.println(f.num);
//1
Zia=(Zi)f;
System.out.println(a.num);
//9
成员函数(非静态)。
参考引用型变量所属的类中是否有调用的函数。
有,编译通过,没有,编译失败。
参考的是对象所属的类中是否有调用的函数。
简单点:
编译时看左边,运行看右边。
静态函数。
参考引用型变量所属的类中是否有调用的静态方法。
编译和运行时都看左边。
其实对应静态方法,是不需要对象的,直接用类名调用即可
1.3.7Instanceof
用于判断对象的具体类型。
只能用与引用数据类型判断。
主要用在判断接收的是否是自己需要的类型。
通常在向下转型前用于健壮性的判断。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- java 知识点