Java语法基础(3)——基础语法中的重难点

1、Java中List和ArrayList的区别

List是一个接口,而ArrayList是List接口的一个实现类。ArrayList类继承并实现了List接口。 

接口和抽象不能被实例化,所以List接口不能被构造(不能创建实例对象),但是可以创建一个对象引用指向继承该接口从而实现面向对象编程中的多态

为什么要用 List list = new ArrayList() ,而不用 ArrayList alist = new ArrayList()呢? 问题就在于List接口有多个实现类,现在你用的是ArrayList,也许哪一天你需要换成其它的实现类,如 LinkedList或者Vector等等,这时你只要改变这一行就行了: List list = new LinkedList(); 其它使用了list地方的代码根本不需要改动。 

List<int> tempMid=new List<int>();中的<>是什么意思呢?泛型,一个泛型类,ArrayList list=new ArrayList();是什么类型的值都可以往list里放的而ArrayList<UserInfo> userlist=new ArrayList()<UserInfo>;则规定了当前userlist只允许存放UserInfo类的对象,其他对象是不能往里放的用泛型可以规定集合的类型,避免不必要的装箱拆箱,减少CPU性能损耗。

2、方法重载

java中的方法重载是为了调用方便,可以优化代码。

overload(方法重载)和override(方法重写)的区别。

方法重载:在同一个类中,方法名相同参数列表不同,和返回值无关。

方法重写:在子父类中,子类有一个和父类方法名相同参数列表相同返回值类型也相同的方法。这个就叫方法的重写

3、形参与实参值的变化

如果方法的参数是基本数据类型,形参的改变不会影响实参。如果方法的参数是引用数据类型,形参的改变会影响实参。

4、继承、构造方法

(1)成员变量

1)父类非私有的成员变量才会继承给子类。所以当我们看到使用子类对象的某个成员变量时,有可能这个成员变量是定义在子类中。也有可能是定义在其父类中。

2)父类中如果已经有了某个成员变量,我们不应该再在子类中定义同名的成员变量。否则可能会导致非常难排查的Bug。

(2)构造方法

1)构造方法不会继承给子类

2)子类的构造中必须调用父类的构造并且要求在第一行。

3)子类的构造方法默认都会在第一行调用父类的无参构造,所以当父类没有无参构造的时候子类构造中会报错(实践中,父类没有无参构造方法也行)(为了用父类的构造方法初始化父类的成员变量,避免子类使用了未初始化的父类成员变量)。解决方案是给父类加上无参构造或者在子类构造中显示的调用父类的有参构造

详细:

构造方法不会被继承,子类继承父类后,子类的有参构造方法要添加super(且写在第一行)调用父类的有参构造方法对父类的成员变量赋值(更方便)。而子类的无参构造方法会自动调用父类的无参构造方法(可不写代码)。

(3)成员方法

父类非私有的成员方法会继承给子类。所以当我们看到使用子类对象的某个成员成员方法时,有可能这个成员方法是定义在子类中。也有可能是定义在其父类中。

 

5、this和super的区别

this就代表本类的,super就代表父类的

访问成员变量时

 

this.成员变量名,本类的成员变量

super.成员变量名,父类的成员变量

 

访问成员方法

this.成员方法名(参数),调用本类的成员方法

super.成员方法名(参数),调用父类的成员方法

 

调用构造方法

this(参数),调用本类的构造方法

super(参数),调用父类的构造方法

 

6、多态时访问成员变量、方法

(1)成员变量

父类成员变量与子类成员变量不应该同名,若出现同名的情况,用父类引用指向子类对象时,若父类引用调用同名的成员变量则会直接调用父类的该成员变量,若父类没有相应成员变量则会编译时报错

(2)成员方法

父类引用指向子类对象时,首先在编译时先检查父类中是否有对应的成员方法,父类没有则报错,然后在运行时检查子类中是否重写该成员方法,没有重写则调用父类方法,已重写则调用子类方法。

(3)多态的使用

分别声明并定义了两只继承了animal的狗、猫

使用统一的feed方法,使子类对象传入给父类引用,用父类引用调用子类方法,从而简化代码。

(4)多态优缺点

优点:提高了代码的复用性和可扩展性

缺点:不能直接使用子类的成员。

7、static修饰符

(1)static是一个修饰符,被其修饰的成员就属于类了。会被类的所有对象所共享。

无论是成员变量,还是成员方法。用static修饰后我们即可以用对象名来调用也可以用类名来调用。一般都使用类名称进行调用。

静态变量:类名.静态变量名

静态方法:类名.静态方法名(参数)

当使用一个类时,会将类的字节码对象加载到方法区中,也就是将编译生成的.class文件加载到内存中的方法区中。内存图如下:

 

 

 

(2)注意事项

1)静态方法中不能直接使用非静态的成员

2)静态方法中不能使用this

(3)理解

1)因为被static修饰的东西就属于类了,所以可以使用类名来调用

2)因为被static修饰的东西就属于类了,类的加载优先于对象,所以在静态方法中,不能使用非静态的成员(Ps:非静态的成员是属于对象),类出现的时候对象还不存在,所以不能使用还不存在的东西

3)因为被static修饰的东西就属于类了,而this代表的某个对象,类加载的时候对象还没创建,所以在静态方法中不能使用this,因为对象都没有出现呢

(4)使用场景

①如果需要共享数据,可以使用static

②如果想要方便调用某些成员,可以使用static修饰(PS:因为就可以直接用类名来调用,不需要创建对象)

8、final修饰符

 

final可以修饰类,成员方法,局部变量,成员变量。修饰后的作用如下:

①可以修饰类,被final修饰的类不能被继承.

②可以修饰成员方法,被final修饰的成员方法不能被重写

③可以修饰局部变量,被final修饰的局部变量就变成了常量,赋值之后就不能被修改

④可以修饰成员变量,被final修饰的成员变量就变成了常量,一旦赋值之后就不能被修改.并且必须初始化。有两种初始化方式,一种是直接赋值,另外一种是要在类的所有的构造方法中对其进行赋值。

 

9、抽象类

(1)格式

抽象方法必须在抽象类中

子类必须重写抽象方法。(以免忘记实现该方法)

(2)特点

抽象类可以有抽象方法,还有就是不能直接创建对象,其他所有都和普通类一样抽象类的子类,要么重写抽象父类中所有的抽象方法,要么子类本身也是一个抽象类

10、接口

(1)概念

接口就是规范\规则,我们可以使用接口来定义一些规则(比如要求某个方法的方法名必须叫什么,方法的参数列表必须是什么,方法的返回值类型必须是什么),可提前给出需求(开发效率更高)。

(2)常用成员

在jdk7版本中接口中只能有常量和抽象方法。

我们接口中定义不了成员变量。因为定义的成员变量默认都会修饰为: public static final(可用类名调用且不能被修改)我们在接口中定义的方法默认修饰符为public abstract,如下

(3)默认方法(不常用)

在jdk8中允许我们在接口中定义默认方法。默认方法允许有方法体。默认方法可以选择不进行重写。便于接口新添方法,继承该接口的类可不做修改。

(4)静态方法(不常用)

在jdk8中允许我们在接口中定义静态方法。静态方法允许有方法体。静态方法不能被重写。

(5)私有方法(不常用)

在jdk9中允许我们在接口中定义私有方法。私有方法允许有方法体。私有方法不可以被重写。不会被继承,私有方法用于接口中多个方法有重复代码时使用。

(6)接口的继承实现关系

(7)抽象类与接口的区别

接口中的基本都是抽象的,而在抽象类中可以有一部分是非抽象方法。而非抽象类中是不可以有抽象方法的。我们就发现接口是最抽象的,其次是抽象类,最后是非抽象类。

所以我们最顶层设计成接口,然后实现类设计成抽象类实现部分抽象方法),抽象类的子类可以设计成非抽象类(对剩下的所有抽象方法进行实现)。

(8)接口在Java源码中的应用

接口List:

 

抽象类AbstractList实现接口List,且只实现部分抽象方法:

未实现get方法

非抽象类ArrayList继承AbstractList,实现所有方法:

11、代码块

(1)静态代码块(重心)

静态代码块在类被加载的时候执行,因此只会执行一次,构造代码块在对象被创建时变执行。

应用:

静态代码块可用于对静态成员的初始化。

(2)局部代码块(不常用)

就是一对花括号“{}”,在其中定义的变量只能在花括号中使用(限定变量作用范围,节约空间)

(3)构造代码块(不常用)

在类中的方法外添加一对花括号“{}”,在类的对象被构造时会执行花括号中的代码。

构造代码块会在调用构造方法的时候执行,并且会在构造方法中的代码执行之前执行。

12、内部类

(1)局部内部类(不常用)

存在某些类,只会在方法中临时使用到,因此直接在该方法中定义一个类,就是内部类。内部类可以访问外部的局部变量(且局部变量为事实常量,即局部变量被赋值之后便没有再更改过值)。

注:在方法中定义的类、变量时不能加权限修饰符的。

(2)成员内部类(不常用,但在源码中常出现)

有时候只在目标类中需要用到一个类,并且这个类可能需要访问目标类私有的成员变量。因此将该类直接定义在目标类中并使用。

定义在类中,方法外。

创建的时候一般在外部类中创建并使用成员内部类。如下:

若需要在外面使用成员内部类,则在外部类中添加一个方法用于创建并返回该内部类对象。在外面定义时用接口类型接收,如下:

特点:

①在成员内部类中可以直接使用外部类的成员,即使这个成员是私有的。

②如果外部类的成员和内部类的成员重名了,可以使用外部类名.this.成员名来表示外部类的成员。

③成员内部类中不能定义静态的成员。(非静态中不用使用静态)

(3)静态内部类(不常用)

静态内部类是在成员内部类的基础上,添加static修饰符,然后就可以在内部类中定义静态成员。

(4)匿名内部类(重心)

匿名内部类本质是一个对象。它是某个类(接口)的子类(实现类)对象。

定义格式与使用:

定义了一个Runner接口的实现类对象,并用父类引用runner接收,然后调用刚刚重写的方法。

在方法参数中使用:

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值