目录
封装
概念:
案例:
应用:
继承
概念
作用
语法
应用场景
传递性
基类
程序中类信息加载
方法重写
概念
语法
重写标签
编辑抽象类
概念
抽象方法
说明
多态
概念
存在条件
多态的使用
多态优点:
多态的转型
final关键字
接口
概念
特点
接口的定义和使用
接口的特性
抽象类与接口的区别
成员变量的区别
构造方法的区别
成员方法的区别
类与接口的关系区别
将类的某些信息隐藏起来(用访问权限修饰符来实现),不让外部直接对其访问,一般可以通过特定的方法来对其隐藏信息的访问,便于控制。
比如我们设计一个学生类,学生有学号,专业,班级,家庭地址,联系方式等属性,但一般家庭住址和联系方式一般不对外开放,需要对其封装,并设置特定的通道(方法)让其访问。
代码:
public class Student {
String id; //没有访问权限修饰符,默认为default
String name;
String grade;
private String address; //此属性用private修饰,只有在此类中可以访问,实现封装效果.
private String Tel;
/**
* 此方法不用public修饰,对外提供访问地址的方法,
* 外界只有通过此方法才可以访问到学生地址
*/
public String getAddress() {
return address;
}
public String getTel() {
return Tel;
}
}
比如我们有这样一个需求: 让一个类在一个程序中,只能创建一个对象。
我们可以将这个类的构造方法设置私有权限,这样这个构造方法在其他类中无法随便使用,在此类中提供一个创建对象的方法,并且控制其次数,这样就解决问题了。
由子类继承父类,子类可以访问父类允许的访问的属性,方法,代码块。
可以实现代码重复利用
使用extends关键字
class 类1 extends 类2{}
表示类1继承了类2
不是任意俩个类就可以继承,继承的俩个类必须是同一类事物,并且级别不同,这时级别低的可以继承级别高的类。比如说我们不能让一只猫继承车,因为猫和车不属于一个类,没有共同属性、特征和功能;也不能让猫继承狗,虽然看起来他们好像有联系,属于同一类,但它们是俩种独立的个体,没有依赖关系,级别相同,不能继承。
但我们可以让猫继承动物,狗也可以继承动物,动物包括猫和狗,他们级别不同,但它们有共同属性和功能:动物都有姓名,品种,年龄等属性,都会吃饭,走等功能。猫和狗可以使用动物的属性和方法,也可以重写方法。
一个类只能直接继承一个父类,继承后子类就可以使用父类非私有的成员。
继承也具有传递性 : C继承B B继承A 那么C就可以使用A和B中的非私有成员。
当一个类没有显示继承某个类,那么这个类默认继承Object类,Object类是所有类的“祖先”,也就是基类。
在创建子类对象后,调用构造方法,从上向下的调用,先初始化父类信息,子类就可以使用这些信息了。
super()方法表示调用父类的无参构造方法,默认存储在子类构造方法的第一行。
父类中的实现方式不能满足子类的需求,子类可以定义自己实现方式。
●方法名相同
●参数列表相同
●返回值相同
●访问权限修饰符不能比父类的权限小
@Override 这是java中提供的一个注解标签(是一种标记,记号),添加此注解的标签表示此方法是从父类中重写过来的,会对其进行验证。
代码:
public class Animal {
String name;
int age;
String species;
public String getName() {
return name;
}
public int getAge() {
return age;
}
public String getSpecies() {
return species;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setSpecies(String species) {
this.species = species;
}
public void run() {
System.out.println("跑");
}
public void eat() {
System.out.println("吃");
}
}
public class Cat extends Animal{
@Override //方法重写标签
/**
* 方法名与父类一致
* 参数列表与父类一致
* 返回值类型与父类一致
* 访问权限修饰符和父类一样(不能比父类小)
*/
public void eat(){
System.out.println("猫吃饭");
}
public static void main(String[] args) {
Cat cat = new Cat();
cat.setName("凯奇");
cat.setAge(12);
cat.run(); //cat类没有定义此方法,可以调用父类的方法
cat.eat(); //Cat类重写了此方法,优先调用本类的方法
}
}
运行结果
如果一个类中包含足够多的信息(抽象方法)来描绘一个具体的对象,这样的类就是抽象类。
是一种特殊的方法,只有声明,没有实现体。适用于只知道有此功能,但不知道具体的实现方式,则可以定义为抽象方法,由其子类具体实现。
abstract 抽象 用 abstract 修饰的方法是抽象方法,没有方法体。
一般用在靠顶层的类,这些类与子类的实现大有不同。
用 abstract 修饰的类是抽象类,其中可能包含抽象方法。
抽象类不能创建对象,因为它含有抽象方法,其他功能与类相同。
抽象类主要用于体系结构上层,用来定义功能。
同一种事物,在不同时刻表现不同的状态。
●要有继承关系(类继承类,类继承抽象类,类实现接口)
●要有重写方法
●父类的引用执行子类的对象
前俩个为前提条件
代码:
Animal a = new Dog(); //Dog 是Animal的子类,创建的Dog对象自动向上转型,变为Animal类型
a.eat();
编译期间 a.eat() a的类型是Animal类,调用Animal类的eat()
运行期间 a指的是Dog对象,运行的是Dog中重写的eat()
针对于非静态成员方法:
编译期间看左边,运行期间看右边
针对于静态成员变量,成员方法:
编译期间看左边,运行期间也看左边
说明:因为静态的信息只有一份,且随着类的加载而加载,创建对象时,静态信息不会加载到对象中。
体现程序的扩展性
自动转型 :
子类继承父类(向上转型:子类型会自动转为父类类型)
强制转型 :
向下转型 父类类型强制转为子类
代码:
Animal a = new Dog();
//自动转型,也称向上转型,创建的Dog对象转换成Animal
Cat cat = (Cat)new Animal();
//强制转型,也称向下转型,创建的Animal对象被强制转换成Cat类型
tips:引用类型数据之间的转换在形式上(语法)与基本类型数据转换一致,可以认为父类是容量较大的数据类型,子类为容量较小的数据类型。
缺点:父类类型不能调用子类特有的方法。
instanceof() 可以用来判断父类引用实际表示的对象是不是指定类型。
final :可以修饰类 属性 方法
修饰类:该类不能被其它类继承
修饰方法:修饰的方法不能被重写
修饰属性: 修饰后的属性是常量,创建时需要对其赋值,赋值后之不能改变。
final属性赋值
● 在声明时同时赋值,往往与static一起使用。
● 声明时不赋值,必须在构造方法中逐一赋值。
● 总的原则:保证创建每一个对象的时候,final属性的值是确定的。
public class FinalDemo {
private int index;
private static final double pai=3.14; //声明时赋值
private final int level; //声明时没有赋值,在无参构造中为level赋值,以保证创建对象时,此值是确定的
public FinalDemo(){
level=0;
}
public FinalDemo(int index){
this.index=index;
level=1;
}
}
错误案例:下面代码在声明和构造方法红都没有赋值
对参数做final修饰。
• 在方法参数前面加final关键字,为了防止数据在方法体中被修改。
public void test(final int x){
// x = 10;
}
错误案例:参数被final修饰,方法体中改变值,IDE会报错
Java接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。
通俗理解: 接口是一个更彻底的、纯抽象的类,可以定义,属性以及抽象方法,和抽象类一样用于体系结构的顶层中,制定规范,设计功能。
●接口中的成员变量默认是静态常量(用final static 修饰)
●可以定义抽象方法(只有方法名,没有方法体)
●JDK8之后可以定义静态方法(可以有方法体),直接通过接口名调用。
还可以定义默认方法(可以有方法体),通过子类调用
●一个接口可以继承多个接口,一个类可以实现多个接口,一个类只能直接继承一个类
(这就是我们使用接口的主要原因,java不像C++可以实现多继承,接口可以解决这个问题)
接口的定义:使用 interface 关键字用来声明一个接口。
[访问修饰符] interface 接口名称 [extends 其他的接口名1,….其他的接口名n]{ // 声明常量 抽象方法 静态方法 默认方法
} 接口的使用:类使用implements关键字实现接口。在类声明中,Implements关键字放在class声明后面。 [访问修饰符] class 类名 implements 接口名1,接口名2……{ } 结合继承: [访问修饰符] class 类名 extends 父类名 implements 接口名1,接口名2……{}
接口是隐式抽象的,当声明一个接口的时候,不必使用abstract关键字
接口中方法可以是抽象的,静态的,默认的
接口中声明的属性默认为 public static final 的
接口不是被类继承了,而是要被类实现 接口不能实例化对象,无构造方法 一个类可以实现多个接口 与继承关系类似,接口与实现类之间存在多态性
一个接口能继承其它多个接口 当类实现接口的时候,类要实现接口中所有的抽象方法。否则,类必须声明为抽象的类
抽象类中的成员变量可以是常量,也可以是变量,而接口的成员变量默认被 public static final修饰。
抽象类只是比较抽象的类,但归根结底还是一个类,所以抽象类有构造方法,而接口不是类,所以没有构造方法。
抽象类的成员方法可以定义抽象的,也可以定义非抽象的;接口在JDK1.7之前只能定义抽象的方法,JDK1.8后可以定义默认方法和静态方法。
类可以继承类,但一个类只能直接继承一个类,可以间接实现多层继承;接口是用来实现的,一个类可以同时实现多个接口。接口与接口的关系与类相似,也是继承关系,一个接口只能直接继承一个接口,也可以实现多层继承。