java开发学习笔记整理导航
概念:
当多个类中具有相同的成员变量和成员方法时,把这些相同的成员抽取出来,放到另一个类中,当某个类需要这些成员时,就不需要再写一遍直接继承该类即可
注意:java中只支持单继承,不支持多继承,支持多层继承
定义:
继承是描述两个类之间的关系
类A继承了类B,那么类A会自动拥有类B中非私有的成员,这个过程就是继承
类A称为子类、类B称为父类
继承的格式
public class 父类{
//共有成员
}
public class 子类1 extends 父类{
//子类可以添加自己特有的成员
}
public class 子类2 extends 父类{
//子类可以添加自己特有的成员
}
提高了代码的可复用性
给多态做了前提
1.继承后成员变量的特点
父子类中的成员变量不同名是不会有任何问题,若同名会根据就近原则,在子类中优先访问子类自己的成员变量
这里要说一下this、super关键字区分变量的不同
this:用来区分本类中成员变量和局部变量的同名情况
super:用来区分子类的成员变量和父类的成员变量同名的情况
但在开发中是不会是父子类的成员变量同名的!所以了解即可
2.继承后成员方法的特点
如果父子类的成员方法不同名,是不会出现任何问题的
如果父子类的成员方法同名了,根据就近原则在子类中优先调用子类自己的方法,在子类的方法中,可以使用【super.方法名()】指定调用父类继承而来的方法
3.继承后构造方法的特点
在说构造方法继承的情况前,先了解下构造方法自身的特点
不写任何返回值,void也不写
方法名必须和类名保持一致
由于构造方法的特殊性,所以构造方法不存在继承
什么是重写:
在子类中出现了和父类一摸一样的方法(方法的声明)那么子类中的方法被称为重写的方法
重写的应用
当子类继承了父类的方法但是发现某些方法的功能比较low时那么子类可以重写此方法
在实际开发中会继承jdk中的类重写某个不满意的方法
注意:
子类方法重写父类方法,必须要保证权限大于或等于父类权限
如果父类的方法是私有的就没有重写私有方法的这种说法,因为私有方法不能继承
在子类中访问变量
this.成员变量名;
访问子类自己的成员变量,如果子类不存在该成员变量,也会访问父类继承而来的成员变量
super.成员变量名;
直接访问父类继承而来的成员变量
这里的成员变量是什么?
优先局部变量,再去子类的成员变量,再去父类继承而来的成员变量
在子类中调用方法
this.成员方法名();
调用子类自己的成员方法,如果子类没有该方法,也会调用父类继承而来的成员方法
super.成员方法名();
直接调用父类继承而来的成员方法
所以只是单单是 成员方法名(); ==> 等价于 this.成员方法名();
this(参数):
调用本类的其他构造,具体是哪一个构造,由参数列表决定
super(参数): 调用父类的构造
子类的所有构造,默认第一行都会有一句代码,super(),调用父类的无参构造
因为Java设计之初遵循了一个原则: 单一职责
父类继承过来的成员变量,由父类的构造进行初始化
子类自己的成员变量,由子类的构造进行初始化
由来:
一个父类有多个子类,所有子类都重写某个方法,那么父类中的这个方法存在的价值就不高了
于是java提出了一个新的方法:抽象方法(抽象方法所在的类必须是抽象类)
抽象类概念:
只要该类是 abstract 修饰的,那么这个类就是抽象类
抽象类可以有抽象方法,也可以没有抽象方法
抽象类定义格式
public abstract class 类名{
//可以有抽象方法也可以没有
}
抽象类使用
不能创建对象,java规定天生做父类,被子类继承的
其他子类继承抽象类后,必须重写抽象类中所有的抽象方法,才能创建对象否则子类还是抽象类
概念:只有方法的声明(方法的头部),没有方法的实现(没有实现体),并加上 abstract 修饰
抽象方法定义格式
public abstract 返回值类型 方法名(参数列表);
抽象类存在的意义: 是作为父类
抽象方法存在的意义: 强制子类必须重写
抽象类不能创建对象
抽象类中,可以有构造方法
抽象类中,不一定包含抽象方法
抽象类的子类,必须重写抽象父类中所有的抽象方法
说接口前再说一下java中的数据类型
基本数据类型:四类八种
引用数据类型:数组、类、接口
什么是接口:
接口就是方法的集合,接口中只允许定义方法,不允许定义成员变量(但可以定义常量),没有构造方法不能创建对象,没有静态代码块
定义常量:
public static final 数据类型 常量名 = 值;
接口中定义的方法
1.接口中不能定义普通的成员方法
2.抽象方法
3.静态方法
4.私有方法
接口定义 interface
格式,会有以下的方法
public interface 接口名{
public abstract void 方法名();//抽象方法,常用
public default void 方法名(){...}//默认方法
public static void 方法名(){...}//静态方法
private void 方法名(){...}//私有方法
private static void 方法名(){...}//私有方法
}
接口不能创建对象,接口是没有构造方法,接口天生做父类,实现可以理解为继承
实现类实现(implements)父接口
实现类可以拥有父类中的非私有成员
实现类必须重写父接口中的所有抽象方法
可以选择性重写默认方法
静态方法没有继承说法,因为静态方法只能通过所在的接口名直接调用
私有方法是不能被继承的
接口的多实现
java中类实现接口可以多实现
格式:
public class 实现类 implements 接口1,接口2...{
//必须重写所有接口中的所有抽象方法,如果接口中有相同的抽象方法,那么实现类只需要重写一次即可
//选择性重写默认方法,如果接口中有相同的默认方法那么实现类必须重写一次
//静态方法和私有方法无影响
}
一个类可以继承一个父类同时可以实现多个接口
格式:
public class 子类/实现类 extends 父类 implements 接口1,接口2..{
//重写父类和所有接口中的所有抽象方法,若有些抽象方法是相同的只需要重写一次
//如果父类的非抽象方法和接口中的默认方法一致,实现类不需要重写,优先调用父类中的非抽象方法
}
类与类是继承,单继承
类与接口是实现,多实现
接口与接口是继承,多继承
格式:
public interface 子接口 extends 父接口1,父接口2 ...{
//自动拥有所有父接口中的所有非私有方法
//如果父接口有相同的默认方法,那么子接口必须重写一次默认方法
}
字面意思理解什么时多态,就是一种事物的多种形态
多态必须满足两个前提
1.必须有继承关系或者实现关系
2.必须有方法的重写(没有重写的多态是没有意义的)
多态的体现
父类类型的变量 指向了 子类类型的对象
父类 变量名 = new 子类();
1.直接多态
Animal an1 = new Dog();
Dog an2 = new BigYellowDog();
Animal an3 = new BigYellowDog();
2.调用方法时参数的多态
//定义方法
public static void test(Animal an) {
}
//调用方法
Dog wangcai = new Dog();
test(wangcai);//wangcai是Dog类,将Dog类作为参数传给test方法,但是形参是Animal类,故为 Animal an = new Dog();
3.调用方法时返回值的多态
//定义方法
public static Animal getAnimal() {
BigYellowDog byd = new BigYellowDog();
return byd;
}
//调用方法
Animal an4 = getAnimal();//相当于返回 new BigYellowDog();
多态调用方法时,编译看父类,运行看子类
所以多态只能运行子父类共有的方法
多态提高程序的扩展性
public abstract class Animal {
public abstract void eat();
}
public class Dog extends Animal {
@Override
public void eat() {
System.out.println("狗说:这肉骨头真好吃...");
}
}
public class Tiger extends Animal{
@Override
public void eat() {
System.out.println("老虎说:这人真好吃...");
}
}
public class Cat extends Animal{
@Override
public void eat() {
System.out.println("猫说:这鱼骨头真好吃..");
}
}
public class Pig extends Animal {
@Override
public void eat() {
System.out.println("猪说:这啥玩意,真好吃...");
}
}
public class TestDemo {
public static void main(String[] args) {
//调用喂猫方法
Cat jf = new Cat();
feedAnimal(jf);
//调用喂狗吃饭
Dog wangcai = new Dog();
feedAnimal(wangcai);
//调用喂猪吃饭
Pig pq = new Pig();
feedAnimal(pq);
//调用喂老虎吃饭
Tiger dbhu = new Tiger();
feedAnimal(dbhu);
}
//定义方法:喂动物吃饭
public static void feedAnimal(Animal an) {
System.out.println("小宝贝,开饭了....");
an.eat();
}
}
多态只能运行子父类共有方法,不能运行子类独有方法
了解向上转型,也就是自动转型
子类类型可以转成父类类型
Animal an = new Dog();//多态
double d = 10;//自动类型转换
向下转型,也就是强制类型转换
父类类型转回子类类型
Animal an = new Dog();//多态
Dog wangcai = (Dog)an;//多态
int i = (int)3.0;//强制转换
编译器在 父类类型 向下转型为 子类类型时,不会检查具体的子类是否正确
但是运行时,会直接程序崩溃
本质是一个运算符
使用格式:
对象名 instanceof 类型
作用:判断左边的对象是不是右边类型的对象
结果:布尔类型
因为要先使用 instanceof 计算后,才能转型
作用:用于修饰
该类不能被继承,好比是“太监”类
格式:
public final class 类名{...}
该方法不能被重写,好比这个方法是最万能的不需要重写
格式:
public final 返回值类型 方法名(参数列表){
}
该局部变量只能赋值一次(常量)
1.定义时直接赋值
2.先定义后赋值
public static void main(String[] args){
final int a = 10;
a = 20;//报错
//或者
final int b;
b = 10;
b = 20;//报错
}
该成员变量只能赋值一次
1.定义成员变量时直接赋值
2.定义成员变量时,不赋值,在构造方法中给其赋值
格式:
public class 类名{
//成员变量
final int age = 10;
//成员变量
final int a;
public 类名(){
this.a = 10;
}
}
该对象保存的地址不能改变,因为指向对象就不能改了,但是对象中的成员变量值可以改变的(除非该成员变量也由final修饰)
格式:
final 类名 对象名 = new 类名();
java中的四种权限修饰符
从小到大
public: 公共修饰符,任何包任何类都可以使用
protected: 受保护修饰符,同包的其他类,或者 不同包的子类中可以使用
不写(default): 默认修饰符, 只能在同包的类中使用
private: 私有修饰符,只能在本类中使用
先了解内部类
一个类A 定义在了另外一个类B的内部:
类A被称为内部类,类B一般称为外部类
根据内部类的定义位置:
1.类中方法外: 成员内部类
2.类中方法中: 局部内部类
内部类定义在了成员位置,称为成员内部类
特点:
成员内部类中可以无条件访问外部类的一切成员
格式:
外部类名.内部类名 对象名 = new 外部类().new 内部类();
语法糖:用来创建抽象类的子类和接口的实现类对象的语法糖
创建抽象类的子类对象:
抽象类 对象名 = new 抽象类(){
//子类必须重写抽象类中所有的抽象方法
};
创建接口的实现类对象:
接口名 对象名 = new 接口(){
//实现类必须重写接口中所有的抽象方法
};
以后会不定期,将自己学习的Java技术整理出来。错误之处还请指出。
祝大家头发多多,bug少少。