疯狂Java学习笔记(010)
回顾 前一天的内容
一、实例变量和局部变量的区别
1. 定义位置和作用范围
实例变量,定义在类中,作用范围是整个类;
局部变量,定义在局部范围内,作用范围是方法内、形参上、代码块;
2. 生命周期
实例变量,随着对象的创建而存在,随着对象消失;
局部变量,方法或语句执行完,变量空间自动释放;
3. 存在的内存位置
实例变量,存在于对象所在的堆内存中;
局部变量,存在于栈内存中;
4. 是否有初始值
实例变量,默认初始值是(0/0.0/false/null);
局部变量,没有初始化值,除了形参,使用前必须赋值;
二、实例变量和静态变量的区别
1. 所属不同
实例变量,属于对象,也称对象(实例变量);
静态变量,属于类,也称类变量;
2. 在内存中位置不同
实例变量,堆内存;
静态变量,方法区;
3. 生命周期
实例变量,随着对象的创建而存在,随着对象消失;
静态变量,随着类的加载而加载,随着类的消失而消失;
4. 调用方法不同
实例变量,只能使用对象名+“. ”的方法调用;
静态变量,可以通过类名+“. ”和对象名+“. ”两种方式调动,推荐使用类名调用;
三、自定义类型当成方法的形参类型
匿名对象的使用:
1>某个对象的方法只能调用一次,没必要起名
2>某个对象是当成参数传给方法
class Student{ ... } class Test{ public void test(Student s){ //这里就可以使用s指向的对象的成员了 } } public class StudentTest{ public static void main(String[] args){ /* Test t = new Test(); Student s = new Student(); t.test(s); */ // new Test().test(new Student()); } }
题目:自定义类型当成方法的返回值类型:
在方法中返回一个自定义类型的对象:
class A{ } class Test{ public A getA(){ A a = new A(); return a; //return new A();可以直接返回自定义类型的对象,而代替上面两句。 } }
四、面向对象的三大特点之一
包括:封装、继承、多态
封装:private 关键字
隐藏一些不想让外界看到的细节。
private常用方法:
1.private 修饰成员变量,并提供对应的公共的getXxx/setXxx方法,比如 private int at;获取方法写成setAt/getAt,这种写法是固定的,在eclipse里会自动生成。
2.private修饰的成员方法,一般都是被一个公共的方法调用,外界可以调用公共方法,
3.private修饰构造方法,让外界不能随便创建对象。
this关键字使用场景:
1.setXxx方法中用于区分局部变量和成员变量,
2.构造方法中调用本类的其他构造方法(this(xxx))
3.成员方法中调用本类的其它成员方法(this.方法(xxx))
题目:this关键字是否可以用来给变量赋值?
class A{ public void test(){ A a; a = this; //把当前对象的引用赋值给局部变量a } }
题目:this关键字是否可以作为方法的返回值类型?
class A{ public A test(){ return this; }
题目:this关键字是否能作为方法的实参?
class A{ public A test(){ test2(this); }
public void test2(A a){ } }
五、构造方法/构造子/构造器:constructor
主要目的:
1.给成员变量赋值,即对象初始化
2.把当前正在构造的对象地址返回
格式:
1. 与类同名,没有返回值
2. 多个构造方法是以重载的形式存在的
3. 构造方法可以互相调用,但不能形成闭环
4. 如果类中没有显示的定义构造方法,系统提供一个默认的空参构造(形参列表和方法体都是空的!)
5. 一旦手动提供了构造方法,系统都不会提供任何构造方法。
总结:在java中,所有的类都至少有一个构造方法。
六、static关键字
1.可以用来修饰成员(成员变量或成员方法),被static修饰的成员,不再属于实例对象,而属于类本身。不会出现在实例对象所在的堆空间,而是类所在的方法区。
2.可以实现在同类,不同实例对象之间的数据共享。
总结:静态的只能访问静态的,非静态的可以访问静态的和非静态的。
七、main方法的参数和使用
String[ ] args,args就是一个数组名
·在启动虚拟机时,类名后的若干个空格分隔的字符串,就是给args传参。
如:java Demo hello world nihao nice to meet you 其中,java启动,Demo类名,后面就是各个元素,都被放到args里面
八、工具类
概念:某个类中的绝大多数方法都是静态方法,基本没有成员变量,方法中使用的数据都是来源于形参,就可以称之为工具类。
特点:①一般不需要外界随便创造对象;
②只让外界通过类名使用类中的方法,要把所有构造方法私有化;
==================================================================
/* 思考题: 如何设计一个类: 让外界不能通过其构造方法去创建对象; 但是却能通过其他方法获取这个类的一个对象的引用。 */ class Dog{ private Dog(){} //公共获取本类对象的方法 public Dog getinstance(){ return new Dog(); } } public class Demo{ public static void main(String[] args){ //Dog d = new Dog().getInstance();这种构造方法不能用 Dog d = Dog.getInstance();//这种方法是可以用的 System.out.println(d);//打印的结果为:DOG@15db9742 } }
=======================================================================
new 工具类的制作 & java 文档注释
/* 工具类: 一个类中,如果所有的方法都是static修饰的,那么它就是一个工具类: 工具类中方法中使用的数据,通常都是来自于形参!!! 一般工具类不提供可用的构造方法!!! 即:在类外不让随便创建工具类的实例对象!! 如何实现?让工具类的构造方法私有化即可!!
数组操作的工具类:
构造私有
方法都是静态的 */
一、类的说明文档的制作——依赖于源文件中的文档注释
工具类的说明书:说明文档(API文档) 对类的说明,方法的签名(访问修饰符,返回值类型,方法名,形参列表...) 一般非开源的工具类,没有源码,必须得到工具类的说明书. 说明书的制作: 文档注释: /** 开头 */结束的多行文字都是文档注释 其中可以使用一些比较特殊的标签: 在类前加的标签 @author 作者 @version 1.0 在方法上可以加的标签: @param 对参数的说明 @return 对返回值的说明
/** 这是数组操作的工具类: @author 弘扬 @version 1.0 */ public class MyArrayTools{ //构造私有化 private MyArrayTools(){} /** 获取一个数组的最大值! @param arr 想获取最大值的数组 @return 这个数组中的最大元素值! */ public static int getMax(int[] arr){ int max = arr[0]; for(int i = 1;i<arr.length;i++){ if(arr[i] > max){ max = arr[i]; } } return max; } /** 获取一个数组的最小值! @param arr 想获取最小值的数组 @return 这个数组中的最小元素值! */ public static int getMin(int[] arr){ int min = arr[0]; for(int i = 1;i<arr.length;i++){ if(arr[i] < min){ min = arr[i]; } } return min; } /** 显示一个数组的所有元素!! @param arr 想要显示的数组 */ public static void printArray(int[] arr){ for(int i = 0;i<arr.length;i++){ System.out.print(arr[i]); if(i != arr.length - 1){ System.out.print(","); } } System.out.println(); } }
/* 测试工具类 */ public class ArrayToolsDemo{ public static void main(String[] args){ int[] arr = {1,2,3,4,5,6,7,8,9}; //使用工具类获取最大值 int max = ArrayTools.getMax(arr); int min = ArrayTools.getMin(arr); System.out.println(max+","+min); //使用工具类显示数组元素 ArrayTools.printArray(arr); } }
二、类的说明文档的制作依赖于源文件中的文档注释:
1.格式:
/** ->开始
*/ ->结束
2.类体前的文档注释:
文字和标签:
@author 作者信息
@version 1.0
3.方法前的文档注释:
文字和标签:
@param 参数名 参数的说明
@return 返回值信息说明
4.提取一个文件中的文档注释:
不是编译过程,并且不会提取单行注释和多行注释,只提取文档注释!!!
javadoc -d mydoc -author -version MyArrayTools.java
API文档的使用:
1.在线版
2.离线版chm格式
3.关注事项:
所在包:java.util一类就需要导包,import java.util.Scanner,但如果是java.lang包下,直接可以用,不用导包。
构造方法,如果是灰色的就是不让用,可用的话就就创建对象
形参,返回值类型
是否是static的
从哪个版本开始
练习:查看API文档,使用Random类的方法 获取一个随机的 1-100之间的整型值!
/* API文档的使用: Math类 查找API文档,Random类,使用它的某个方法,获取一个1-100之间的随机int数,改写以下程序!! */ import java.util.Scanner; import java.util.Random; public class GuessNum{ public static void main(String[] args){ Scanner s = new Scanner(System.in); // // int r = (int)(Math.random() * 100 + 1); //改造,使用Random类的方法获取一个int随机数 Random random = new Random(); int r = random.nextInt(100) + 1; while(true){ System.out.print("输入一个数:"); int x = s.nextInt(); if(x > r){ System.out.println("大了"); }else if(x < r){ System.out.println("小了"); }else{ System.out.println("猜对了"); break; } } } }
代码块:block
三种:
1.局部代码块:
在方法体中出现的{}
作用:及时释放局部变量占用的栈空间
特点:局部代码块中的变量只在{}中有效
2.构造代码块:
在成员位置出现的{}
作用:抽取出多个构造方法中共同的代码.
特点:"一次"构造方法的调用,就执行一次,并不是一个构造方法调用,都执行一次!
3.静态代码块:
用static修饰的构造代码块就是静态代码块
作用:对静态成员变量进行初始化的
特点:随着类的加载而执行,多次创建对象,不会多次执行.
代码块的细节:
每一次构造方法的调用,都会先执行构造代码块中的内容,然后才是构造方法中的内容
并不是"每个"构造方法被调用,都会执行构造代码块中的内容!!!
静态代码块:
伴随着类的加载而执行的,多次创建对象并不会导致静态代码块的多次执行!只是在第一次加载类的时候执行一次!!!
就是静态代码块就执行一次,构造代码块有几个new a()就执行几个,,
多个构造代码块按出现的顺序执行!
多个静态代码块按出现的顺序执行!
*/
class A{
static{
System.out.println("静态代码块2");
}
{
System.out.println("haha2");
}
public A(){
this(10);
System.out.println("空参的构造方法");
}
public A(int a){
System.out.println("带参的构造方法");
}
{
System.out.println("haha1");
}
static{
System.out.println("静态代码块1");
}
}
public class BlockDemo2{
public static void main(String[] args){
new A();//类的加载导致静态代码块的执行,创建对象导致构造代码块的执行!!
new A();//创建对象导致构造代码块的执行!!
}
}
面向对象编程三大特点之二:继承extends
继承的由来:
多个类中出现重复的成员定义,那么就可以将共同的部分抽取到一个单独的类中,让多个类和这个单独的类产生一个继承关系(使用extends关键字).
那么在多个类中就无须定义重复的部分了.
抽取出来的单独的类称为父类,超类,基类.
从这个父类继承的多个类则称为子类.
/* 继承/扩展:extends 多个类中出现了重复的成员定义:就可以把重复的内容抽取到一个单独的类中. 让多个类和单独的类产生一个关系.在多个类中,就无需再定义重复的内容. 被抽取出来的类称为父类,超类,基类. 多个类称为子类. */ /* class Student{ public String name; public int age; public void eat(){ System.out.println("eat()..."); } } class Teacher{ public String name; public int age; public void eat(){ System.out.println("eat()..."); } } */ class Person{ public String name; public int age; public void eat(){ System.out.println("eat()..."); } } //extends关键字后是父类,前是子类,子类中无须再定义父类中出现的代码 class Student extends Person{ } //extends关键字后是父类,前是子类,子类中无须再定义父类中出现的代码 class Teacher extends Person{ } public class ExtendsDemo{ public static void main(String[] args){ Student s = new Student(); s.name = "zhangsan"; s.age = 10; System.out.println(s.name +","+ s.age); s.eat(); Teacher t = new Teacher(); t.name = "lisi"; t.age = 20; System.out.println(t.name +","+ t.age); t.eat(); } }
继承的优点:
1.实现了代码的复用,简化代码书写.
2.是多态的前提!
语法:
修饰符 class 子类名 extends 父类名{...}
继承的特点:
1.Java不支持多继承,支持多层继承!!!
一个类只能有一个直接父类,父类还可以再有父类...,也就是继承体系.
2.父类私有成员不能被继承,公有的方法能被继承,可以通过公有的方法,间接的访问父类的私有成员!!!
class A{ }
class B extends A{ }
class C extends B{ }
/* Java中继承只支持单继承,不支持多继承 一个子类只能有一个直接父类.不能有多个父类. java中不支持多继承,支持多层次继承!!! 父类中私有的成员不能被继承!! */ class GrandFather{ } class Father extends GrandFather{ private int age = 10; public int getAge(){ return age; } private void test(){ System.out.println("Father.test()"); } } class Mother{ } class Son extends Father{ //getAge(); } /* class Son extends Father,Mother{ } */ public class ExtendsDemo2{ public static void main(String[] args){ // Father f = new Father(); // System.out.println(f.age); Son s = new Son(); // System.out.println(s.age);//父类私有成员不能被继承!!! System.out.println(s.getAge()); } }
/* 继承关系中,子父类中的成员变量的关系: 1.子类中没有任何和父类同名的成员变量 2.子类中出现了和父类同名的成员变量,使用子类的 子类的方法中,使用到的变量,有三种情况: 1.先在方法体内找 2.在子类的成员位置找 3.在父类的成员位置找 */ class Father{ int a = 10; } class Son extends Father{ // int a = 30; //子类特有的变量 int b = 20; public void test(){ // int a = 40; System.out.println(a);// System.out.println(b); } } public class ExtendsDemo3{ public static void main(String[] args){ new Son().test(); } }
super关键字
super关键字和this关键字的作用类似.
this表示的是当前正在调用当前这段代码的对象的引用.
super表示一个对象的直接父类对象的引用!
/* super关键字: 子类对象所在的堆空间中包含的一个父类对象的引用! 子类对象创建前,父类对象必须先创建出来!!!这个过程是系统自动完成的. super关键字的使用场景: 1.子类出现和父类同名的成员,父类的成员会被隐藏.使用super可以访问到父类被隐藏的成员super.变量名 2.在子类方法中显式调用父类的某些方法.super.方法名() 3.在子类的构造方法中,显式调用父类的构造方法!!! 子类的构造方法默认有一条语句:super(); 这句就是在调用父类的空参构造方法.把父类对象创建出来 如果父类没有空参构造方法,那就会报错. 此时,一般会调用父类其它的构造方法,super(xxx) java 中每个类的构造方法的第一条语句,默认都是super(); */ class Father{ int age = 30; //父类空参构造 public Father(int a){ System.out.println("父类空参构造"); } public void method(){ System.out.println("father.method"); } } class Son extends Father{ int age = 10; //子类的所有构造方法中,默认第一条都是super(); //除非子类的构造方法中使用this调用本类的其它构造方法,或者super(xxx); public Son(){ //super(); //调用父类带参的构造方法 super(0); System.out.println("子类的空参构造"); } public Son(int x){ this();//此时就没有super();了 } public Son(int x,int y){ super(); } public void test(){ //引用父类中被隐藏的成员变量 System.out.println(age + "," + super.age); } //子类中出现了和父类同样的方法,称之为重写! public void method(){ //调用父类被隐藏的方法 super.method(); System.out.println("son.method"); } } public class SuperDemo{ public static void main(String[] args){ Son s = new Son();// // s.test(); // s.method(); } }
即:可以理解为:一个实例对象的内部都包含一个其直接父类的对象!
这样做的目的是为了保证能正确的从父类中继承成员!!!
例如父类中的实例变量,是属于父类实例对象的,存在于父类对象所在的堆空间中.
如果父类对象不存在的话,那么子类对象就不能继承这个成员了!
从图中也可以看出:
1.其实父类对象中的所有成员(包括私有的),都是存在的,只不过不能直接访问而已!
2.父类被覆盖的成员,可以通过super关键字访问
方法的重写:override/overwrite
子类中出现和父类方法签名一致的方法,此时父类的方法被隐藏了.即:子类重写了父类的方法.
子类重写父类的方法:
1.只能在访问权限上放大.其余的都保持一致!!!
2.静态的方法只能使用静态方法重写.
3.子类重写方法中想调用父类被隐藏的方法,可以使用super.方法名(xxx)的方式!!!
但是,static方法中不能使用super关键字!此时只能用类名调用.
A.全否定 B.部分保留
/* 方法的重写:overwrite override 子类中出现了父类一样的成员方法.父类中的方法就被"覆盖"了.称为子类重写了父类的方法. 1.子类重写父类的方法,权限修饰符可以扩大范围:或者保持一致!!! 2.除了访问权限外,其余都和父类方法保持一致!!! 3.子类重写的方法中,可以通过super.方法名(xxx)的方法,去调用父类被覆盖的方法. static静态方法中,不能出现this,super关键字 不论this,super它们都是实例对象的引用!! static出现时,还没有实例对象. */ class Father{ //什么都不写,就是默认的访问权限修饰符, void test(){ System.out.println("father.test()"); } public static void method(){ System.out.println("father static method"); } } class Son extends Father{ //重写父类方法 public void test(){ //访问被重写的父类方法 super.test(); System.out.println("son.test()..."); } /* public static void method(){ // super.method(); Father.method(); System.out.println("son static method"); } */ //子类特有的方法 public void test2(){ } public void test3(){ } } public class OverwriteDemo{ public static void main(String[] args){ Son s = new Son(); // s.test(); s.method(); s.test2(); } }
面试题:
说说override,overwrite,overload三者的区别.
静态方法中不能出现this或者super关键字
因为:不论this或者super都是堆空间中对象的引用.
但是static方法是随着类的加载而存在的,此时还没有存在实例对象.
final关键字:
- final + 类名:此类不能有子类
- final + 方法名:此方法不能被子类重写
- final + 变量名:只能被赋值一次!也就是final常量!
Java中的常量有两种:
1.字面量常量
2.final常量
它们的特点是值是不可变的!
静态的final变量:
1.定义的时候就赋值
2.定义时不赋值,在静态代码块中赋值
非静态的final变量:
1.定义的时候就赋值
2.定义时不赋值,在构造代码块中赋值
3.定义时不赋值,构造代码块中不赋值,在构造方法中赋值
总结:非静态的final变量,只需要在构造方法调用完成之前赋值就可以了!!
最常用的场景就是在定义的时候就赋值!!!
/* final关键字: final + 类名:不能有子类 final + 方法名:方法不能被子类重写 final + 变量名:只能被赋值一次! 静态的final变量: 1.定义的时候就赋值 2.定义时不赋值,在静态代码块中赋值 非静态的final变量: 1.定义的时候就赋值 2.定义时不赋值,在构造代码块中赋值 3.定义时不赋值,构造代码块中不赋值,在构造方法中赋值 总结:非静态的final变量,只需要在构造方法调用完成之前赋值就可以了!! 最常用的场景就是在定义的时候就赋值!!! */ /* final class A{ } class B extends A{ } */ class A{ public final void test(){ System.out.println("final test()"); } } class B extends A{ static final int b = 10; static{ b = 10; } final int a; { a = 30; } public B(){ // a = 20; } /* //final方法不能被重写 public void test(){ System.out.println("B final test()"); } */ } public class FinalDemo{ public static void main(String[] args){ System.out.println(new B().b); } }
抽象类:abstract关键字
抽象方法:是没有方法体的方法,就是抽象方法.
抽象类:包含抽象方法的类,就是抽象类.
抽象方法和抽象类,都必须使用abstract关键字修饰.
抽象类的特点:抽象类不能手动的去用new对象!
抽象类是依赖其实现子类去实例化对象的.
即:抽象类中定义的抽象方法,只有在子类对象中才能使用!!!
抽象类的继承:
抽象类的子类如果把抽象父类中的所有抽象方法都实现了,那么此子类就是一个实现子类,这个子类就可以创建对象.
否则,只要没有完全把所有的抽象方法都实现,此子类就依然是一个抽象子类.依然不能实例化对象.
/* 抽象方法:没有方法体的方法(就是没有{}的方法),就是抽象方法.必须被abstract关键字修饰. 一旦一个类中包含了抽象方法,那么本类也是一个抽象类,也必须用abstract关键字修饰. 抽象类不能直接实例化对象. 抽象类是通过子类实例化对象的. 子类必须实现抽象父类中的所有抽象方法.否则子类也是一个抽象类. */ abstract class Animal{ //没有方法体的方法,就是抽象方法,必须用abstract修饰!!! public abstract void eat(); } //实现子类:不包含任何抽象方法的类 class Dog extends Animal{ //实现抽象方法 public void eat(){ System.out.println("dog eat"); } } class Cat extends Animal{ public void eat(){ System.out.println("cat eat"); } } public class AbstractDemo{ public static void main(String[] args){ //抽象类是否能实例化对象? // Animal a = new Animal();// Animal是抽象的; 无法实例化 Dog d = new Dog(); d.eat(); Cat c = new Cat(); c.eat(); } }
回顾
一、文档注释
1.文档注释→说明书的制作
格式:/** */
1>直接出现的文字,特殊的标签;
2>类上:
@author
@return
3>方法上:
@param 参数名
@return
4> 使用特殊的工具提取文档注释,提取一个源文件中的文档注释成html页面。
语法:javac -d c:/mydocs -author -version Demo.java
其中javadoc命令只是提取文档注释,并不会编译源文件!
二、API文档的使用
1一般情况下,知道类名,去搜索相关的说明
1>包名,是否是java.lang包下,是,则程序直接使用,否则需要导包
2>构造方法是否可用,可以,则一般情况下会创建对象,在使用他的方法。
如果不能用构造方法:
此类是工具类;
此类提供了静态放发,用于获取本类的一个实例对象;
此类是一个抽象类,只能是通过实现子类实例化!
3>方法的修饰符:
static
返回值类型
方法参数列表,返回值信息
方法异常信息
2.代码块的执行顺序
静态→构造代码块→构造方法
三、面向对象的特点之二:继承
1.概念:继承是java中实现代码复用的方式!
2.子类中出现和父类同名的成员(成员变量和成员方法)
父类中的成员都是被隐藏起来了,并没有消失!
super关键字可以把父类隐藏的成员暴露出来!!
3.子类方法中使用变量的查找顺序:
1.>先在局部位置(直接在方法体中定义的变量,方法的形参上)找
2.>在子类的成员位置找
3>在父类的成员位置找
四、方法的重写
子类中出现了和父类方法签名一致的方法,就是方法的重写!!
方法重写的特点:
子类方法可以把访问权限放大,其余的都和父类方法保持一致!
静态方法只能用静态重写!!(静态方法实际上是没有重写的概念的!!)
五、super关键字
1.子类方法中使用被隐藏的父类变量:super.变量名
2.子类方法中使用被重写的父类方法:super.方法名(xxxx)
3.子类构造方法中使用super(xxx),调用父类的构造方法
4.子类所有构造方法默认第一句都是 super()
除非子类构造第一句使用的是,this(),super(xxxx)
5.子类实例化对象时具体步骤:
1>执行子类的类加载过程(伴随着子类静态代码块的执行,直接父类也会执行加载)
2>成员变量的初始化(系统默认初始化,显示初始化)
3>构造方法初始化(构造代码块,构造方法)
4>把实列对象的地址返回
在子类成员变量初始化,构造代码块,构造方法中,如果出现了其它的类的实例化过程,那么这个被引用的类的初始化过程也会被执行(1-4步)
Dog{
static{}
{}
int age = 10;
public Dog(){...}
}
Person{
String name = null;
Dog d = null;
{
}
public Person(){...}
}
六、final关键字
- final + 类名:此类不能有子类(不能被继承)
- final + 方法名:此方法不能被子类重写
- final + 变量名:只能被赋值一次!也就是final常量!
ExtendsDemo.java 子类实例化的具体过程
七、抽象类:
1>抽象类:使用abstract修饰的类就是抽象类,包含抽象的方法的类就是方法类!
2>抽象方法:没有方法体的方法就是抽象方法!
抽取父类时,子类的方法签名相同,但是具体实现不同,父类中只能抽取方法签名
这个没有方法体的方法就是抽象方法!!
题目:抽象类如何使用?
- 抽象类的特点:抽象类不能手动的去用new对象!
- 抽象类是依赖其实现子类去实例化对象的.
- 即:抽象类中定义的抽象方法,只有在子类对象中才能使用!!!
==============
作业:
1.Java中实现继承使用的关键字是?
2.Java中是否有多继承?是否有多层继承?
3.父类中私有的成员是否能被子类继承?是否能被使用?
4.一旦子类中出现了和父类一样的成员定义的话,父类中的同样的成员如何被使用?
5.父类构造方法能被子类继承么?
6.说说override,overwrite,overload三者的区别.
7.为什么子类的构造方法默认第一句都是super();?
(子类实例化之前父类的实例化对象必须先存在?)
子类需要从父类中继承一些成员,而父类构造方法的主要目的就是对成员进行初始化的.
子类实例化对象前,父类的构造方法必须被调用!!!
8.子类重写父类方法的时候,能改变的部分是?不能变的部分是?
只有访问权限可以放大,或者相同.其余都不能变!
9.什么是抽象方法?什么是抽象类?抽象类如何实例化?
没有方法体的方法就是抽象方法.
使用abstract修饰的类就是抽象类,其中不一定包含抽象方法.
抽象类不能直接实例化,通过实现子类间接实例化!!
编码:
1.设计一个Phone类,拥有基本的属性和一个基本的打电话的功能.
设计一个NewPhone类,从Phone类继承基本的属性和功能,并重写打电话功能.在基本的打电话功能基础上,增加显示通话时间的功能.
分别对两个类的对象做测试.
2.设计一个抽象类,包含一个抽象方法,让不同的子类有不同的实现.并做测试!
3.思考题
编程实现如下场景:
动物园饲养员负责饲养动物,他有一个饲养的方法,只要是动物他都可以进行饲养.
动物有两种:Dog,Cat,它们都有一个show方法.用于显示各自饿了的信息,每种动物实现的细节可能不同.
饲养员在饲养动物时,先让动物show方法调用一下,然后再喂食.
使用继承和抽象类的知识对以上场景进行模拟实现.
提示:饲养员的饲养方法的参数是什么类型?是具体的Dog,还是Cat?还是一个其他的类型?
=====================