Java面向对象总结、注意事项
Java面向对象1. 方法
[*] 用private修饰field;
[*] 外部通过public的getXxx()和setXxx()方法;
[*] this变量:方法内部的this始终指向当前该类的实例;
[*] 可变参数:类型... 名称,如func(String… names),相称于数组类型
利用可变参数的好处:
1. 假如利用数组,需要先构建数组,而利用可变参数不需要
2. 利用数组可以传入null,但可变参数在传入0个参数时,担当的是空数组而不是null
[*] 传递参数时:
[*]基本类型参数,是值的复制,互不影响
[*]引用类型参数:调用方和吸取方指向的是堆内存的同一个对象或数组
2. 构造方法
[*]通过构造方法初始化实例;
[*]构造方法没有返回值(void也没有),方法名和类名相同,通过new来调用;
[*]默认有空参构造器,定义有参的,空参的就没了;
[*]引用类型未初始化是null,int是0,布尔是false;
[*]为方便代码复用,可在构造器内调用其他构造器; this(age,“lzh”);
3. 方法重载
[*]类中一系列方法的功能类似,只是参数不同,可将其举行方法重载
[*]方法名相同,返回值通常相同,如int indexOf(int ch); int indexOf(String str);
4. 继续
[*]extends将Student继续Person,会得到Peson的全部功能:字段和方法。父类中严禁定义同名字段;
[*]一个类没有extends时,会默认继续Object;
[*]子类继续了全部(不包括构造方法),但是无法访问私有字段、私有方法;
[*]父类字段改为protected字段可以被子类访问;protected字段和方法被子类所访问;
[*]super:表示父类;子类引用父类字段时:super.fieldName,因为子类继续后拥有该字段,也可写成this.fieldName;
[*]任何类的构造器的第一句必须是父类的构造器,默认省略了super();所以父类要有无参构造器或显示调用其他super;
[*]制止继续:final class,表示该类不能继续
[*]向上转型:People变量可以指向Student实例,People p = new Student();
因为Student继续Person,拥有Person全部功能。
如许 子类类型 => 父类类型
[*]向下转型:父类类型强制转换为子类类型,Student s = (Student)p;
若p指向的就是People类型,则向下转型失败,因为p原本就是父类类型,子类多的功能无法实现;
instanceof操作符:判断一个实例是不是某个类型(或者该类型的父类型)
Person p = new Student();
if(p instanceof Stundet){
Student s = (Student)p;
}
[*]子类和父类是is关系,利用继续;子类和某个类是has关系,应把它作为子类的一个字段
5. 多态
[*]方法重写:子类定义了一个和父类方法署名完全相同的方法;
[*]Person p = new Student();假如子类重写父类run方法,那么p调用的是子类的run方法
实例方法是基于`运行时的实际类型的多态调用,而不是变量的声明类型
[*]多态:某个类型的方法调用,其真正执行的方法取决于运行时期的实际类型的方法
public void runTwice(Person p) {
p.run();
p.run();//无法知道传入的参数实际类型究竟是Person,还是Student.
//当传入可变参数时,我们不需要知道它们属于什么类型,只需要知道调用run方法会调用它实际类型的run
}
多态允许添加更多类型的子类实现;
[*] 重写Object方法:
[*]toString()
[*]equals()
[*]hashCode()
[*] 在子类中调用父类被重写的方法:super.run();
[*] 利用final设置一个父类方法不能被子类重写;final修饰的字段不能被修改
6. 抽象类
[*]假如父类的被重写方法run(),没有实际意义,不需要实现任何功能,只是为了定义方法署名以供子类去重写,可将其声明为抽象方法:abstract void run(); 没有方法体
[*]抽象方法无法执行,那么地点的类就无法实例化,所以类也要声明为抽象类:abstract class People{ };
[*]设计抽象类就是用于继续,抽象类逼迫子类实现抽象方法。抽象方法相称于定义了规范;
[*]面向抽象编程:利用抽象类去引用具体的子类,尽量引用高层类型,避免引用实际子类型;
Person s = new Student();
Person t = new Teacher();
// 不关心Person变量的具体子类型:
s.run();
t.run();
7. 接口
[*]抽象类中可以有字段、非抽象方法,但接口中没有字段,全都是抽象方法;
interface Person{
void run();
String getName();
}
[*]接口是比抽象类还抽象的纯抽象接口,方法都是public abstract,所以这俩可以不写
[*]类是实现接口:implements,接口可以多实现;
[*]特殊的是:接口可以定义常量、default方法
[*]接口interface之间也可以继续,相称于扩展了接口的方法
[*]一般来说,公共逻辑得当放在abstract class中,具体逻辑放到各个子类,而接口层次代表抽象程度。https://img-blog.csdnimg.cn/6215c57233fd4252b4e6ba7910c28f3e.png
在利用的时候,实例化的对象永远只能是某个具体的子类,但总是通过接口去引用它,因为接口比抽象类更抽象:
List list = new ArrayList(); // 用List接口引用具体子类的实例
Collection coll = list; // 向上转型为Collection接口
Iterable it = coll; // 向上转型为Iterable接口
[*]接口的default方法:default void run(){ }; 实现类不必重写default方法;
目的:给接口新增一个方法时,要修改全部实现子类,所以新增一个default方法,如许子类可以不重写该方法,假如需要,也可以重写;
8. 静态字段、方法
[*]前面class里定义的都是实例字段:每个实例都有独立的字段,每个实例之间互不影响;
[*]静态字段:static修饰;一个全部该类的实例共享的字段
[*]利用 类名.static字段 来访问静态字段;
[*]静态方法:static void run(){}; 利用类名调用
因为静态方法属于类自身,所以静态方法内部无法利用this、无法访问实例字段,只能访问静态字段;
常用于工具类Arrays.sort()、Math.random(),辅助方法:main()方法;
9. 包
[*]办理类名辩论,如不同人都写了个Person类
[*]一个类总属于某个包,比如Person只是简写的类名,全名应是 包名.Person
[*]在定义class的首行声明该类地点的包
[*]JVM运行时,看的是全类名,包不同,类就不同;
包没有父子关系,java.util和java.util.zip是不同的包
[*]包作用域:同一个包的类,可以访问包作用域的字段方法;缺省就表示包作用域(默认)
[*]import:类中引用其他class,利用import导入该类,之后就可以写简朴类名了;否则利用时要写全类名;
[*]编译器编译时,遇到一个class,假如是完备类名就直接查找;假如是简朴类名就按顺序:
[*]先查找当前package是否有该类;
[*]再查找import导入的包中是否有;
[*]末了在java.lang包中查找
因此,编译器编译时自动导入当前package的其他class、java.lang.*(不包括lang包内部的包,java.lang.reflect这些)
10. 内部类
[*]被定义在另一个类的内部;不能单独存在,必须依附一个外部类的实例
[*]先创建Outer实例,再通过Outer.new来调用内部类的构造器:Outer.Inner inner = outer.new Inner();
[*]Inner Class有this指向自己,还有一个Outer.this指向外部实例;
[*]Inner Class可以修改外部类的private字段方法;
[*]匿名类:不需要在外部类中明白定义;在方法内部利用匿名类来定义(局部内部类)
通常是实例化接口,但接口不能实例化,需要实例化该接口的一个实现类,而该实现类名字不重要;
Runnable r = new Runnable(){
//实现必要的抽象方法。。。
}
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]