- Java的三大特征
- 重载和重写的区别
- 接口和抽象类的区别
- Java中的内部类
- 成员内部类
- 静态内部类
- 匿名内部类
- 局部内部类
- 局部内部类
Java语言的三大特征,封装、继承和多态
封装是指对象属性的私有化,提供一些可以访问属性的方法(get、set),通过get和set方法来获得对象的属性
第一步:属性私有化,private
第二步:对外提供简单的操作入口,对外提供公开的set方法和get方法,并且这两个方法都不带有static,为对象级别的方法可以在set方法中设立关卡,来保 护数据的安全性
注意:java开发规范中,set方法和get方法不可以带static
继承是指一个类继承另一个类,子类继承父类,子类拥有父类所有的属性和方法,并且子类可以根据自己的需要来扩展属性和重写方法。
- 子类拥有父类对象的所有属性和方法,但是父类中的私有属性和方法子类不能访问,只是拥有
- 子类可以拥有自己的属性和方法
- 子类可以用自己的方式实现父类
① B类继承 A类,则称 A类为超类(superclass)、父类、基类,B类则称为子类(subclass)、 派生类、扩展类。
② java 中的继承只支持单继承,不支持多继承,C++中支持多继承,这也是 java 体 现简单性的一点,换句话说,java 中不允许这样写代码:
class B extends A,C{ }。
③ 虽然 java 中不支持多继承,但有的时候会产生间接继承的效果,
例如:class C extends B,class B extends A,也就是说,C 直接继承 B,其实 C 还间接继承 A。
④ java 中规定,子类继承父类,除构造方法外,剩下都可以继承。但是私有的属性无法在子类中直接访问,可以通过间接的手段
⑤ java 中的类没有显示的继承任何类,则默认继承 Object 类,Object 类是 java 语言提供的根类(老祖宗类),也就是说,一个对象与生俱来就有 Object 类型中所有的特征。
⑥ 继承也存在一些缺点,例如:CreditAccount 类继承 Account 类会导致它们之间耦合度非常高,Account 类发生改变之后会马上影响到 CreditAccount 类
对继承自Object
多态是指同一个行为具有不同的表示形式或者形态能力。多态就是一个接口,使用不同的实例对象进行不同的操作。
多态表示多种形态:编译的时候一种形态,运行的时候是一种形态。
向上转型和向下转型的概念
第一个:向上转型
子 --> 父 (自动类型转换)
第二个:向下转型
父 --> 子 (强制类型转换,需要加强制类型转换符)
注意:
Java允许向上转型,也允许向下转型
无论是向上转型,还是向下转型
两种类型之间必须有继承关系,没有继承关系编译器报错
在 Java 中有两种形式可以实现多态:继承(多个子类对同一方法的重写)和接口(实现接口并覆盖接口中同一方法)
有了封装,有了这种整体的概念之后,对象和对象之间产生了继承,有了继承之后,才有了方法的覆盖和多态。
重载和重写的区别重载是发生在同一个类中,具有相同的方法名,不同的参数列表和返回值
重写是发生在子类和父类中,子类需要根据需要重写父类的方法
接口和抽象类的区别接口:通过interface实现
- 和类是并列的关系
- 接口中的所有方法必须是抽象的
- 接口中方法定义默认为public abstract 类型,成员变量默认为public static final类型。
抽象类:通过extends实现
- 一个类中有抽象方法,这个类就变成了抽象类
- 抽象类中的class前面必须有abstract修饰
- 抽象类中可以有普通的方法,也可以有抽象的方法
- 子类继承父类必须重写全部的抽象方法
- 子类实现方法必须含有相同的或者更低的访问级别(public->protected->private)
抽象类和普通类的区别:
- 抽象的方法的修饰符必须为public和protected
- 抽象类不能被实例化
- 如果一个类继承了抽象类,则子类必须实现父类抽象的方法,如果子类没有实现父类抽象方法那么子类也是一个抽象类
接口和抽象类的区别:
- 一个类只能继承一个抽象类,一个类可以继承多个接口
- 实现接口的关键字为implements,继承抽象类的关键字为extends
- 抽象类中有构造方法,接口没有
- 抽象类中有普通方法,接口必须都是抽象方法
- 接口中的方法的修饰符是public,抽象类的抽象方法可以有private、protected、default
- 抽象类中的成员变量可以是各种类型的,接口中的成员变量只能是public static final类型的
接口和抽象类如何选择:
- 当我们需要一组规范的方法的时候,我们就可以用接口,在具体的业务中,来对接口进行实现,能达到以不变应对万变,多变的需求的情况我们只需要改变对应的实现类 。
- 如果多个实现类中有相同可以复用的代码这个时候就可以在实现类和接口之间,添加一个抽象类,把公共的代码抽出在抽象类中。然后要求不同实现过程的子类可以重写抽象类中的方法,来完成各自的业务。
内部类有四种:静态内部类、局部内部类、匿名内部类和成员内部类
成员内部类public class InnerClass{
public class InnerclassA{
}
}
成员内部类是以来外部类而才能在,再创建一个成员内部类之前需要先创建外部类对象
创建成员内部类的方法:
- 在外部类的构造方法中,通过创建一个new InnerClassA();来创建一个内部类对象
- 不在外部类内部时,通过外部类对象.new 内部类构造器,来创建内部类对象
- 同时在内部类中可以定义public、private、protected、default等,不可以定义static属性
package InnerClass;
public class InnerClass {
public class InnerClassA{
public InnerClassA() {
System.out.println("InnerClassA被创建");
}
}
public InnerClass() {
//在构造方法中创建内部类对象。
InnerClassA innerClassA = new InnerClassA();
System.out.println("InnerClass被创建");
}
public static void main(String[] args) {
InnerClass innerClass = new InnerClass();
//在外部创建成员内部类
InnerClassA innerClassA = innerClass.new InnerClassA();
}
}
- 外部类对象可以通过内部类的对象以用来访问内部类中定义的字段,而内部类对象可以通过访问外部类对象中所有的字段
package InnerClass;
public class InnerClass {
private int out1 = 1;
int out2 = 2;
public int out3 = 3;
protected int out4 = 4;
public class InnerClassA{
private int in1 = 1;
int in2 = 2;
public int in3 = 3;
protected int in4 = 4;
public InnerClassA() {
System.out.println("InnerClassA被创建");
System.out.println(out1);
System.out.println(out2);
System.out.println(out3);
System.out.println(out4);
}
}
public InnerClass() {
//在构造方法中创建内部类对象。
InnerClassA innerClassA = new InnerClassA();
System.out.println("InnerClass被创建");
System.out.println(innerClassA.in1);
System.out.println(innerClassA.in2);
System.out.println(innerClassA.in3);
System.out.println(innerClassA.in4);
}
public static void main(String[] args) {
InnerClass innerClass = new InnerClass();
}
}
静态内部类
一个类中的静态成员,我们可以使用类名.静态成员名来访问,同样的一个静态内部类不需要依赖其外部类对象
package InnerClass;
public class InnerClass02 {
private int out1 = 1;
int out2 = 2;
public int out3 = 3;
protected int out4 = 4;
static class staticinner{
private int in1 = 1;
int in2 = 2;
public int in3 = 3;
protected int in4 = 4;
static int in5 = 5;//可以定义static属性
public staticinner() {
System.out.println("staticinner被创建");
}
}
public InnerClass02() {
//在构造方法中创建对象
staticinner staticinner = new staticinner();
System.out.println("innerclass02被创建");
}
public static void main(String[] args) {
InnerClass02 innerClass02 = new InnerClass02();
//不依赖外部类直接创建对象
staticinner staticinner = new staticinner();
}
}
静态内部类创建对象的时候无需依赖外部类对象。但是,内部类中也无法访问外部类的非静态成员。因为外部类的非静态成员需要依赖于外部类对象,而静态内部类就是独立于外部类对象存在的,不需要依赖于外部类对象,所以静态内部类不可以访问外部类的非静态成员。
匿名内部类最常见的形式为:新建一个接口对象/类对象,实现这个接口/类中原有的方法时出现
package InnerClass;
public class InnerClass03 {
public static void main(String[] args) {
MyMath myMath = new MyMath();
//匿名内部类,重写了sum方法
myMath.sum(new Compute() {
@Override
//重写sum方法
public int sum(int a, int b) {
return a+b;
}
},100,200);
}
}
//计算接口
interface Compute {
int sum(int a, int b);
}
class MyMath{
public void sum(Compute c,int x, int y){
int revalue = c.sum(x,y);
System.out.println(x + " + " + y + " = " + revalue);
}
}
局部内部类
局部内部类,其声明在一个方法体/一段代码块的内部,而且不在定义类的定义域之内便无法使用。
package InnerClass;
public class InnerClass04 {
public void doSome(){
class innerclass{
}
}
}
System.out.println(x + " + " + y + " = " + revalue);
}
}
局部内部类
局部内部类,其声明在一个方法体/一段代码块的内部,而且不在定义类的定义域之内便无法使用。
package InnerClass;
public class InnerClass04 {
public void doSome(){
class innerclass{
}
}
}



