一.抽象类
1.抽象类和抽象方法的概念
1) 抽象方法: 将共性的行为(方法)抽取到父类之后,由于每一个子类执行情况不一样,所以父类中不能确定具体的方法体,该方法就;可以定义为抽象方法。。
格式:访问修饰符 abstract 返回类型 方法名(形参)
2)抽象类: 如果一个类中存在抽象方法,那么该类就必须声明为抽象类;
格式:访问修饰符 abstract 类名{
}
1.2抽象类的特点
1)抽象类不能实例化(也可重写其中的方法),但是可以通过之类间接实例化;
2).抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类
3).抽象类必须继承,抽象类的子类要么重写抽象类中的所有抽象方法要么是抽象类;
4).可以有构造方法
5).abstract关键字只能用来修饰类和方法;
6).抽象方法不能用private,final,static关键词来修饰,这三个关键词都是和方法重写违背的
private(访问限定词)修饰方法,将方法私有化,子类无法访问;
----final关键字
方法: 表明该方法是最终方法,不能被重写
类:表明该类是最终类,不能被继承;
变量:叫着常量,只能被赋值一次;
final修饰的变量是基本数据类型: 那么变量储存的数据值不能发生改变;
是引用类型 : 那么变量储存的地址值不能发生改变,对象内部的可以改变。
----static 修饰方法,方法静态方法,与类绑定,所以子类不能重写;
package comwww;
public class tset5 {
public static void main(String[] args) {
//Person1 sc= new Person1(),抽象类不能实例化,不能利用new来创建对象;
Person1 sc=new Person2("朱朱朱");//多态
Person1 sc1=new Person1() {//重写其中的方法让其可以运行
@Override
public void sleep() {
}
}
sc.eat();
sc.sleep();
}
}
abstract class Person1{
private String name;
public Person1() {}
public Person1(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void eat(){
};
public abstract void sleep();//木有方法体,为抽象方法,需要在加上abstract 进行修饰;
}
class Person2 extends Person1{
public Person2(){};
public Person2(String name) {
super(name);
}//对父类进行重构
//需要对所以抽象方法进行重写,否则报错;
@Override
public void sleep() {
System.out.println(getName() + " sleep");
}
}
二.static
(存储在一块固定的内存区域(静态区),随着类的加载而加载,优先于对象)
1.静态变量
static 静态变量:静态变量被所有的对象共享,在内存中只有一个内存块,它当且仅在类初次加载时会被初始化,优先与对象(是类拥有的,可以理解为)。而非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个内存块,互不影响。
static的初始化按照定义的顺序进行初始化,且只初始化一次。
2.静态变量的内存原理
3.static修饰类的成员方法
类内部的static静态方法:不能访问类的非静态方法和非静态成员变量;
非static 可以访问所有;
因为类的加载优于对象,非静态方法和非静态变量是伴随对象出现的。
package comwww;
public class test7 {
public static void main(String[] args) {
static2.name="xhu";//只加载一次,所有创建的对象该变量不会改变;
static2.kk();
static2 staticc=new static2();
staticc.kk();//静态方法、静态变量可以直接用类调用也可以用创建对象调用//
staticc.name="1";/
}
}
class static2 {
static String name;
int age;
public static void kk() {
System.out.println(name);
//System.out.println(age),此时会报错;
}
}
运行结果:xhu
xhu
三.多态
--概念:同类型的对象,表现出不同形态(对象的多种形态);
--表现形式:父类 对象名称 = 子类名称
--前提:有继承、接口关系
有父类引用指向子类对象;
有方法重写
学生形态 对象
Student s=new Student();
人的形态 对象
Person p=new Student();
Student 的父类为人;
不理解的话可以参考低等数据类型,赋值给高等数据类型,比如char可以赋值给int;
2.应用场景
部分主要代码
public class text7 {
public static void main(String[] args) {
student sc = new student();
sc.setAge(18);
sc.setName("朱朱朱");
teacher sc1 = new teacher();
sc1.setAge(20);
sc1.setName("酷酷酷");
io(sc);
io(sc1);
}
public static void io(Person3 s){
s.show();
}
}
class student extends Person3{
@Override
public void show() {
System.out.println("学生的信息为"+getName()+" "+ getAge());
}
}
好处:使用父类型作为参数,可以接受所有的子类对象,体现多态的扩展性与便利。
3.多态调用成员的特点:
---调用成员变量:
编译看左边:javac编译代码的时候,会从左边的父类中看看有木有这个变量,如果有编译成功,如果木有编译失败。
运行也看左边,实际上获取的就是左边父类中成员变量的值。
---调用成员方法
编译看左边:javac编译的时候,会先看左边父类有无这个方法,有,编译成功;
运行看右边:实际上是运行的子类中的方法,如果木有重写该方法,还是调用的父类该方法,如果重写写了,调用的是重写后的。
可以理解为: 他们是父类不同的状态,本质其实还是父类,变量肯定按照父类的,方法如果重新写了,虚拟表中就重新写了,掉用新的。
Animal a=new Dog();
a是Animal类型的,所有默认从Animal中找
成员变量,在子类的对象中,会把父类的成员变量继承下来
成员方法:如果子类对虚方法表进行了重新写,那么虚方法表会把父类方法覆盖
内存图
四.权限修饰符
实际开发中一般只用private和public
--成员变量私有
--方法公开
特例:如果方法中的代码是抽取其他方法的中共性代码,这个方法一般也私有。
五.代码块
局部代码块:提前结束变量的声明周期,用完就释放(已经淘汰)
构造代码块:不够灵活
package comwww;
public class tast9 {
public void main(String[] args) {
//局部代码块;
{
int a=10;
System.out.println(a);
}
//System.out.println(a),这样写就会报错,已经a变量已经用完内存已经释放;
}
}
class Student12{
private String name;
private int age;
public Student12() {
this(null,0);
}
public Student12(String name, int age) {
System.out.println("开始创建对象了");
this.name = name;
this.age = age;
}
}
静态代码块: 格式static{}
特点:需要通过static关键字修饰,随着类的加载而加载,并且自动触发、只执行一次;
使用场景: 在类加载的时候,做一些数据初始化的时候使用。
public class tast9 {
//可以理解为全局变量
static ArrayList<user>list=new ArrayList<>();
ststic{
int a=10;
}
public void main(String[] args) {
六.接口
1.接口解释
接口就是一种规则,对行为的抽象;
package comwww;
public class Frog extends Animal implements Swim{
public Frog() {
}
public Frog(String name,int age){
super(name,age);
}
@Override
public void eat() {
System.out.println("青蛙在吃虫子");//父类的抽象,重写;
}
@Override
public void swim(){
System.out.println("青蛙在游泳");
}
}
//接口
public interface eat {
public void eat();
}
2.接口中成员特点
---规则不能发生改变
---接口中成员变量
只能是常量:
默认修饰符 :public static final
----构造方法 :
没有,接口不能创捷对象,也不需要给之类成员变量赋值
-----成员方法:
只能是抽象方法
默认修饰符:public abstract
JDK7之前只能定义抽象方法。
JDK8:接口中可以定义有方法体的方法(默认(default)、静态(static));
JDK9:接口中可以定义私有方法
3.接口与类之间的关系
---类与类的关系
继承关系,只能单继承,不能多继承,但是可以多层继承;
---类与接口之间的关系
实现关系,可以但实现,也可以多实现,还可以在继承一个类的同时实现多个接口(把所有抽象方法全部重写);
注意:
抽象方法重名(包括接口与抽象父类,接口与接口)怎么办,取并集;
重名的返回值要一样,否则报错;
---接口与接口的关系
继承关系,可以但继承,也可以多继承
注意:如果实现了最下面的子接口,那么就需要重写所有抽象方法
3.1 接口之间的继承关系
接口eatt
public interface eatt {
void eat();
void eat2();
}
接口eat
public interface eat {
public void eat1();
void eat2();
}
package comwww;
public class Frog extends Animal implements eat,eatt{
@Override
public void eat() {
System.out.println("接口eat运行");
}
@Override
public void eat1() {
System.out.println("接口eat1运行");
}
@Override
public void eat2() {
}
}
package comwww;
public class text11 {
public static void main(String[] args) {
Frog s = new Frog();
s.eat();
s.eat1();
}
}
运行结果:
接口eat运行
接口eat1运行
3.2 static修饰方法
接口中的static方法与类中的static方法很像,都是直接调用,静态方法必须写函数体,否则会报错,但是与类中不同的是,类中也可以通过创建对象后调用,但是接口只能 接口名。static方法调用。
可以供外部调用。
public class text11 {
public static void main(String[] args) {
Frog s = new Frog();
s.eat1();
eat.eat2();
}
}
public interface eat {
public void eat1();
public static void eat2() {
System.out.println("eat2");
}
}
3.3 接口中的默认方法(default)
接口中的 默认方法,此时有fang'fa在实现类中可重写,也可不重写,创建对象后可以直接调用;
如果存在多个接口名字相同的默认方法,系统不知道默认的是哪一个,所以必须重新写。
public interface eat {
public void eat1();
public default void eat2() {
System.out.println("eat2");
}
}
class Frog implements eat{
@Override
public void eat1() {
System.out.println("Frog eat1");
}
}
class text11 {
public static void main(String[] args) {
Frog s = new Frog();
s.eat1();
s.eat2();
}
}
运行结果:
Frog eat1
eat2
3.4 接口中private私有方法
如果两个默认方法中重复的内容多等情况,可以单独写一个方法调用,为了防止该方法被外界调用可以加上private
public interface eat {
public static void eat1(){
ea4();//静态只能调用静态的
System.out.println("eat1");
}
public default void eat2() {
ea3();
System.out.println("eat2");
}
private void ea3(){//只供本接口使用
System.out.println("ea3接口");
}
private static void ea4(){
System.out.println("ea4");
}
}
2.接口与接口的继承
eat为eatt父类
该子类接口在实现时候需要重写父类中的所有抽象方法;
3.适配器