抽象类:abstract
抽象:不具体,看不明白。抽象类表象体现。
在不断抽取过程中,将共性内容中的方法声明抽取,但是方法不一样,没有抽取,这时抽取到的方法,并不具体,需要被指定关键字abstract所标示,声明为抽象方法。
/**
* 当多个类中出现了相同功能,但是功能主体不同,这时可以进行向上抽取。这时只抽取功能的定义。而不抽取功能主体。
*
* 抽象类的特点:
* 1.抽象方法一定在抽象类中。
* 2.抽象方法和抽象类都必须被abstract关键字修饰。
* 3.抽象类不能用new创建对象,因为调用抽象方法没有意义。
* 4.抽象类中的抽象方法要被使用,必须由子类重写其所有的抽象方法后,建立子类对象调用。
* 如果子类只重写了部分抽象方法,那么该子类还是一个抽象类。
*/
代码示例:
//定义一个抽象类Student1
abstractclass Student1 {
//抽象方法study
abstract void study();
}
//基础班类
classBaseStudent extends Student1 {
//实现study方法的具体细节
void study() {
System.out.println("Basestudy");
}
}
//加强班类
classAdvStudent extends Student1 {
//实现加强班类的study方法的具体细节
void study() {
System.out.println("Advstudy");
}
}
抽象类的细节:
1:抽象类中是否有构造函数?有,用于给子类对象进行初始化。
2:抽象类中是否可以定义非抽象方法?
可以。其实,抽象类和一般类没有太大的区别,都是在描述事物,只不过抽象类在描述事物时,有些功能不具体。所以抽象类和一般类在定义上,都是需要定义属性和行为的。只不过,比一般类多了一个抽象函数。而且比一般类少了一个创建对象的部分。
3:抽象关键字abstract和哪些不可以共存?final , private , static
4:抽象类中可不可以不定义抽象方法?可以。抽象方法目的仅仅为了不让该类创建对象。
模板方法设计模式:
*什么是模板方法呢?
* 在定义功能时,功能的一部分是确定的。但是有一部分是不确定的。而确定的部分在使用不确定的部分。
* 那么这时就将不确定的部分暴露出去,由该类的子类去完成。
*/
代码示例:
//获取时间类
abstractclass GetTime {
//获取runCode函数的运行时间方法
public final void getTime() {
long start = System.currentTimeMillis();
//不确定的功能代码
runCode();
long end = System.currentTimeMillis();
System.out.println("毫秒数:" + (end - start));
}
//不确定的方法runCode,需要由子类去实现
public abstract void runCode();
}
//GetTime类的子类,该类需要实现runCode方法
classSubTime extends GetTime {
//实现runCode方法的具体细节
public void runCode() {
for (int x = 0; x < 100000; x++) {
System.out.println(x);
}
}
}
//模板测试类
publicclass TemplateDemo {
public static void main(String[] args) {
//创建子类的实例对象
SubTime time = new SubTime();
//调用getTime方法,打印结果
time.getTime();
}
}
接口:
/*接口:初期理解。可以认为是一个特殊的抽象类,当抽象类中的方法都是抽象方法时。那么该类可以通过接口的形式来表示。
* class用于定义类,interface用于定义接口。
*
* 接口定义的格式特点:
* 1.接口中常见的定义:常量、抽象方法。
* 2.接口中的成员都有固定的修饰符。只要写上interface,就算没写这些固定修饰符,系统会默认自动加上的。
* 常量 public static final
* 方法public abstract
* 记住:接口中的成员都是public修饰的。
*
* 接口是不可以创建对象的,因为有抽象方法。需要被子类实现,子类对接口中的抽象方法全都重写后才可以实例化。
* 否则子类还是一个抽象类。
*
* 一个类可以同时实现多个接口。也是对多继承不支持的转换形式。java支持多实现。
其实java中是有多继承的。接口与接口之间存在着继承关系,接口可以多继承接口。
*
* 接口的好处: 1.对外暴露规则。
* 2.提高了功能的扩展性。
* 3.降低了耦合性。
* */
代码示例:
//定义一个接口Inter
interfaceInter {
//静态常量
public static final int CHANG_LIANG_MING =23;
//抽象方法show
public abstract void show();
}
//定义一个接口InterA
interfaceInterA {
//静态常量AGE
public static final int AGE = 22;
//抽象方法show
public abstract void show();
//抽象方法method
public abstract void method();
}
//定义一个Demo1类
classDemo1 {
public void function() {
}
}
//定义一个Test类,继承了Demo1类,并且实现了Inter和InterA两个接口
classTest extends Demo1 implements Inter, InterA {
//实现接口的show方法
public void show() {
}
//实现接口的method方法
public void method() {
}
}
//接口A
interfaceA {
public abstract void methodA();
}
//接口B继承接口A
interfaceB extends A {
public abstract void methodB();
}
//interfaceC extends B, A { 接口与接口中可以实现多继承
//接口C继承接口B
interfaceC extends B {
public abstract void methodC();
}
//接口E继承C
classE implements C {
//实现A接口的methodA方法
public void methodA() {}
//实现B接口的methodB方法
public void methodB() {}
//实现C接口的methodC方法
public void methodC() {}
}
多态:
/*多态:理解为事物存在的多种体现形态。人:男人、女人 动物:猫、狗...
* 猫 m = new 猫(); 多态: 动物 m = new 猫();
* 1.多态的体现。
* 父类的引用指向自己子类的对象。父类的引用也可以接收自己子类的对象。
* Animal= new Dog();
* 2.多态的前提。
* 必须类与类之间有关系,要么继承,要么实现。还有一个前提:存在方法重写。
*
* 3.多态的好处。
* 多态的出现大大的提高了程序的扩展性。
*
* 4.多态的弊端。
* 提高了扩展性,但是只能使用父类的引用访问父类中的成员。
* * */
class 毕姥爷{
void讲课(){
System.out.println("企业管理");
}
void钓鱼(){
System.out.println("钓鱼");
}
}
class 毕老师 extends 毕姥爷{
void讲课(){
System.out.println("JAVA");
}
void看电影(){
System.out.println("看电影");
}
}
class {
publicstatic void main(String[] args) {
毕姥爷 x = new 毕老师(); //毕老师对象被提升为了毕姥爷类型。
// x.讲课();
// x.看电影(); //错误.
毕老师 y = (毕老师)x; //将毕姥爷类型强制转换成毕老师类型。
y.看电影();//在多态中,自始自终都是子类对象在做着类型的变化。
}
}
如果想用子类对象的特有方法,如何判断对象是哪个具体的子类类型呢?
可以可以通过一个关键字 instanceof ;//判断对象是否实现了指定的接口或继承了指定的类
格式:<对象 instanceof类型>,判断一个对象是否所属于指定的类型。
Student instanceofPerson = true;//student继承了person类
在多态中,成员函数的特点:
* 编译时期:参阅引用型变量所属的类中是否有调用的方法,如果有,则编译通过。如果没有,则编译失败。
* 运行时期:参阅的是对象所属的类中是否有调用的方法。
* 简单的总结就是:成员函数在多态调用时,编译看左边,运行看右边。
*
* 多态中成员变量的特点:无论编译还是运行都是参考左边。
*
* 多态中静态成员函数的特点:无论编译还是运行都是参考左边。
/* Object:是所有对象的直接或者间接父类。传说中的上帝。
* 该类中定义的是所有对象都具备的功能。
*
* 如果自定义类中有比较相同的方法,没有必要重新定义。只要重写父类中的方法,建立自己特有的比较内容即可。
* */
具体方法:
1,booleanequals(Object obj):用于比较两个对象是否相等,其实内部比较的就是两个对象地址。
而根据对象的属性不同,判断对象是否相同的具体内容也不一样。所以在定义类时,一般都会复写equals方法,建立本类特有的判断对象是否相同的依据。
publicboolean equals(Object obj) { //Objectobj = new Demo();
if (!(obj instanceof Demo))
return false;
Demo d = (Demo) obj;
return this.age == d.age;
}
2,StringtoString():将对象变成字符串;默认返回的格式:类名@哈希值 = getClass().getName() +'@' + Integer.toHexString(hashCode())
为了对象对应的字符串内容有意义,可以通过复写,建立该类对象自己特有的字符串表现形式。
publicString toString() {
return "Person age=" + age;
}
3,inthashCode():返回该对象的哈希码值。支持此方法是为了提高哈希表的性能。
通常equals,toString,hashCode,在应用中都会被复写,建立具体对象的特有的内容。
内部类:
如果A类需要直接访问B类中的成员,而B类又需要建立A类的对象。这时,为了方便设计和访问,直接将A类定义在B类中。就可以了。A类就称为内部类。内部类可以直接访问外部类中的成员。而外部类想要访问内部类,必须要建立内部类的对象。
/* 一、内部类的访问规则:
* 1.内部类可以直接访问外部内的成员,包括私有的。
* 之所以内部类能直接访问外部类中的成员,是因为内部类中持有了一个外部类的引用,格式为 外部类名.this
* 2.外部类要访问内部类,必须先建立内部类对象。
*
* 二、访问格式:
* 当内部类定义在外部类的成员位置上,而且非私有,可以在外部其它类中建立该内部类对象。
* 格式为 外部类名.内部类名 内部类对象名 = new外部类名().new内部类名();
* Outer.Inter in = new Outer().newInter();
*
* 三、当内部类在成员位置上时,就可以被成员修饰符所修饰。
* 如:private 将内部类在外部类中进行封装。
* static 内部类就具备了static的特性。
* 当内部类被static修饰后,只能直接访问外部类中的static成员,出现了访问局限。
*
* 在外部其它类中如何访问static内部类里的非静态成员呢?
* new Outer.Inter().function();
*
* 在外部其它类中如何访问static内部类里的静态成员呢?
* Outer.Inter.function();
*
* 注意:当内部类中定义了静态成员,该内部类也必须是static的。
* 当外部类中的静态方法访问内部类时,内部类也必须是静态的。
*
* 当描述事物时,事物的内部还有事物,该事物就由内部类描述,因为内部类中的事物可以使用外部类中的事物的内容。
* class Body {
*
* private class Heart {
*
* void jump() {
*
* }
* }
*
* public void method() {
*
* new Heart().jump();
* }
* }
* */
classOuter {
int x = 3;
static class Inter { //内部类
int x = 5;
public static void function() {
int x = 8;
System.out.println("InterClass="+ x);//打印8:x 打印5:this.x 打印3:Outer.this.x
}
}
public void method() {
System.out.println("OuterClass="+ x);
Inter i = new Inter();
i.function();
}
}
publicclass InterClassDemo {
public static void main(String[] args) {
Outer o = new Outer();
// o.method();
// Outer.Inter in = new Outer().newInter();//1.建立非静态内部类对象。先创建外部类对象,再创建内部类对象
// in.function();
// Outer o2 = new Outer(); //2.建立非静态内部类对象。先建立外部类对象,再通过外部类对象建立内部类对象。
// Outer.Inter in2 = o2.new Inter();
Outer.Inter in = new Outer.Inter(); //1.建立静态内部类对象,访问静态内部类格式。
new Outer.Inter(); //2.建立静态内部类的匿名对象。
new Outer.Inter().function(); //访问静态内部类中的非静态成员方法。
Outer.Inter.function(); //访问静态内部类中的静态成员方法。
}
}
------- android培训、 java培训、期待与您交流! ----------