在一个类中,一个方法可以调用这个类中的其余方法(包括自身,即递归)以及成员变量,不能在方法中再定义方法。方法重载(Overload,两同一不同)
与权限修饰符、返回值类型、形参名无关,比如public void add(int m,int n)和 public void add(int n,int m)就不算重载。可变形参
public static void test(int a ,String[] books){};与例子写法是等价的。
前提是实参和形参类型一致。import
比如使用import com.*; 是指导入 com 目录下的所有类,这里只有 Test 类,并不会导入在 com 的下一级 lc 目录中的 Phone 类。
如:java.sql.Date date = new java.sql.Date(time);
外部类只能用 public 和缺省修饰。构造器(Constructor)
这里的“使用”是指:直接使用属性或通过“对象.属性”访问,而非通过如 getter 的方法访问。
- 在其他包的子类中,可以直接使用或通过子类对象间接使用父类中 protected 修饰的属性或方法。
- 在其他包的子类中 ,new 出来的父类对象,无法使用父类中 protected 修饰的属性或方法。
- 其他包的类,通过调用子类对象,无法使用父类中 protected 修饰的属性或方法。
- 在其他包的子类中,通过其他子类的对象,无法使用父类的protected修饰的属性和方法。
比如,可以实现 Serializable 接口,用于实现bean的持久性。this 关键字
this()和 this(实参列表)只能声明在构造器首行,且不能出现递归调用。
子类会继承父类所有的实例变量和实例方法。
子类不能直接访问父类中私有的(private)的成员变量和方法,需通过 get/set 方法。
一个父类可以同时拥有多个子类,但一个子类只有一个父类。
类加载的时候,先加载父类,再加载子类,即先加载父类的静态代码块。
@Override:写在方法上面,用来检测是否满足重写的要求。这个注解就算不写,只要满足要求,也能够重写。
① 父类私有方法不能重写。 ② 跨包父类中缺省的方法也不能重写
也就是,返回值类型不变或是返回值类型的子类。
static 修饰的方法不能被重写。
一般可以省略,但是当出现重写了方法或子类、父类有重名属性的情况,调用父类的方法或属性需要加上“super.”。方法前面没有 super.和 this.:先从子类找,如果没有,再从父类找,再没有,继续往上追溯。
总结:有super.则直接从父类找,没有super.则从子类开始找。子类调用父类的构造器
当方法需使用重名的属性时,采用就近的原则。
- 子类中定义过的方法(即子类中重写过的方法和子类中新定义的方法,不包括从父类继承但没重写的方法)优先找子类的属性。
- 父类中拥有的方法找的是父类的属性,无法访问子类的属性。
- 当子类中重写过的方法前加上 super.后,使用的是父类的方法,所以就近找父类的属性。
父类中的 setInfo()没有在子类中重写,若在代码中调用,则修改的是父类的 Info 属性。
对于每个构造器,"this(形参列表)" 和 "super(形参列表)"只能二选一,没有给出"this(形参列表)",则默认调用"super()",即调用父类中空参的构造器,那么父类空参构造器中已初始化的属性无需在子类构造器中反复初始化,除非初始值不同。
一个引用类型的变量可能指向(引用)多种不同类型的对象。常用多态的地方:
使用父类做方法的形参,是多态使用最多的场合。即使增加了新的子类,方法也无需改变,提高了扩展性,符合开闭原则(对扩展开放,对修改关闭)。
使用了多态后,同名属性则会使用父类的,子类独有的属性无法使用,子类新定义的方法无法使用,只有重写过的方法能使用。除非向下转型才能使用子类的属性或新定义的方法。虚方法调用(Virtual Method Invocation)
根据左边的引用类型,决定调用父类的属性还是子类的属性,而方法是调用的子类对象重写过后的方法。复制代码
- Base b = new Sub(); //引用类型是 Base,调用Base的属性,即 1。
- System.out.println(b.a);
- Sub s = new Sub(); //引用类型是 Sub,调用 Sub 的属性,即 2。
- System.out.println(s.a);
- class Base{
- int a = 1;
- }
- class Sub extends Base{
- int a = 2;
- }
Java 中的虚方法是指在编译阶段不能确定方法的调用入口地址,在运行阶段才能确定实际被执行的方法。向下转型
复制代码
- //Base是父类,sub和sub1是两个子类。
- Sub b = new Sub(); //声明的引用类型为Sub
- System.out.println(b instanceof Sub1); //这里会报错,因为Sub和Sub1没有继承关系。
- Base b = new Sub(); //声明的引用类型为Base
- System.out.println(b instanceof Sub1); //不会报错
在 JDK 9 中此方法已经被标记为过时的。getClass()
随类加载而加载,内存空间里就一份(因为类只加载一次),被类的对象共享。jdk6 放在方法区,jdk7 及以后放在堆空间。可以通过类或对象调用。
每个对象拥有一份实例变量,随对象的创建而加载,存放在堆空间的对象实体中。只能通过对象调用。
随类加载而加载,可以通过类或对象调用,静态方法内可以使用静态变量和其他的静态方法,不可以调用非静态的属性和方法。
静态方法中不能使用 this 和 super。
在静态类中使用静态变量和其他静态方法时,可以省略“类名.”。
静态代码块的执行总先于非静态代码块的执行。
理解的时候,可以把非静态代码块当作类中直接调用父类的那些构造器的一部分,放在那些构造器的前几行(但在父类的构造器后),一调用构造器就先执行非静态代码块。
若调用的构造器使用了this(...),非静态代码块不看成这些构造器的一部分,而看成在this(...)里面,直到找到那个直接调用父类的构造器,将代码视为其一部分。复制代码
- public A(){ //执行的时候可以理解成这样
- [super();] //父类构造器,可以不写,默认调用父类空参构造器。
- {
- ... //非静态代码块
- }
- System.out.println("我是直接调用父类的构造器");
- ...
- }
- public A(int a){
- this(); //使用了this(),则没有调用父类的构造器,属于间接调用,因为A()中调用了父类构造器。
- System.out.println("我不是直接调用父类的构造器");
- }
- Base base = new Base(1,"lc");
- /*
- new Base(1,"lc")调用的是Base(int b, String name)构造器,其中又调用了this(b),即public Base(int b)。
- public Base(int b)又调用this(),即public Base()。
- public Base()没有显式给出调用父类构造器,则默认调用父类空参构造器。从以上描述可以看出,public Base()是类中直接调用父类的构造器,非静态代码块可以看为它的一部分,但是在父类的构造器之后。
- public A()是类中直接调用其父类Object的构造器,而Object没有任何输出,然后执行类A的非静态代码块,再执行类A构造器的其余代码,执行完再执行Base的非静态代码块,再执行Base()的其余代码以及其他构造器的代码。
- */
- /*
- 结果为:
- 我是代码块A
- 我是构造器D
- 我是代码块Base
- 我是构造器A
- 我是构造器B
- 我是构造器C
- */
- class Base extends A{
- int b = 1;
- String name;
- {
- System.out.println("我是代码块Base");
- }
- public Base(){
- System.out.println("我是构造器A");
- }
- public Base(int b) {
- this();
- this.b = b;
- System.out.println("我是构造器B");
- }
- public Base(int b, String name) {
- this(b);
- this.name = name;
- System.out.println("我是构造器C");
- }
- }
- class A{
- {
- System.out.println("我是代码块A");
- }
- public A() {
- System.out.println("我是构造器D");
- }
- }
final 修饰引用类型变量时,其指向的对象的地址值不能变,即不能再给这个变量赋另外的对象,但对象里面的属性值能修改。abstract
有抽象方法的类一定是抽象类,没有抽象方法的类也可以是抽象类。
子类必须重写完所有抽象方法才能实例化。复制代码
- public abstract void eat(); //抽象方法声明,没有“{}”。
属性默认用public final static修饰,可以省略不写。
声明抽象方法默认用public abstract修饰,可以省略不写。
不可以声明构造器、代码块。
类必须重写接口中所有的抽象方法,否则必须声明为抽象类。
接口可以继承接口,且可以多继承。interface cc extends AA,BB{}
接口也有多态,也可以作函数的形参,接口名 base = new 实现类();,只能调用接口有的方法,不能调实现类独有的方法。
可以创建引用类型为接口的数组,但存放的元素必须是,重写完所有抽象方法的实现类所创建的实例。复制代码
- Eatable[] eatable = new Eatable[3];
- eatable[0] = new Chinese();
- eatable[1] = new American();
欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) | Powered by Discuz! X3.4 |