继承(子类 is a 父类)
//父子类有成员变量,成员函数重名(覆盖 重写)时。创建的对象是谁,就优先用谁。如果没有,则向上找。
//@override: 检测是否是正确的覆盖重写
public class Extends {
public static void main(String[] args) {
Teacher teacher = new Teacher();
teacher.method(); //父类方法执行
teacher.methodT(); //30 20 10
Assistant ass = new Assistant();
ass.method(); //父类方法执行
ass.methodE(); //子类运行方法e
}
}
//父类
class Employee {
int num = 10;
public void method() {
System.out.println("父类方法执行");
}
public void methodE() {
System.out.println("父类运行方法e");
}
}
//子类1
class Teacher extends Employee{
int num = 20;
public void methodT(){
int num = 30;
System.out.println(num); //30
System.out.println(this.num); //20
System.out.println(super.num); //10
}
}
//子类2
class Assistant extends Employee{
@Override
public void methodE() {
System.out.println("子类运行方法e");
}
}
继承关系中的构造函数
/*
1.子类构造方法中有一个隐含的“super()”调用,所以一定是先执行父类构造,后执行子类构造。
2.子类构造可以通过super关键字调用父类重载构造。
3.super的父类构造调用,必须放在子类构造方法的第一个语句。
总结:
子类必须调用父类且在最前面调用父类构造,不写默认赠送“super()”,写了则用指定的super调用。
*/
public class ExtendsConstructor {
public static void main(String[] args) {
Zi zi = new Zi();
}
}
class Fu {
public Fu(int num) {
System.out.println("父类有参构造");
}
}
class Zi extends Fu {
public Zi() {
super(10);
System.out.println("子类构造");
}
}
抽象(abstract)
public class Abstract {
public static void main(String[] args) {
Cat cat = new Cat();
cat.eat();
Dog2ha ha = new Dog2ha();
ha.sleep();
}
}
//有抽象方法的一定是个抽象类
abstract class Animal {
public abstract void eat();
public abstract void sleep();
}
class Cat extends Animal {
@Override
public void eat(){
System.out.println("fish");
}
@Override
public void sleep(){
System.out.println("miaomiaomiao");
}
}
//抽象类不一定有抽象方法(该子类还有子类,抽象方法在孙子类中实现)
abstract class Dog extends Animal {
@Override
public void eat() {
System.out.println("bone");
}
}
class Dog2ha extends Dog {
@Override
public void sleep() {
System.out.println("hahaha");
}
}
class DogGolden extends Dog {
@Override
public void sleep() {
System.out.println("huhuhu");
}
}
接口(interface)
接口中抽象方法和默认方法
/*
接口就是多个类的公共规范。
是一种引用类型,最重要的内容就是其中的,抽象方法。
*/
/*
接口中定义抽象方法:
修饰符必须是两个关键字:public abstract,但可以选择性省略不写
接口中定义默认方法:(可以解决接口升级的问题)
修饰符为关键字:public default,public可以省略
*/
interface MyInterfaceAbstract {
//这是一个抽象方法
public abstract void method1();
//这也是抽象方法
public void method2();
//这也是抽象方法
abstract void method3();
//这也是抽象方法
void method4();
//这是一个默认方法
default void methodDefault(){
System.out.println("接口中的默认方法");
}
}
/*
接口的使用:
接口不能直接使用,必须定义一个“实现类”。
实现类必须覆盖重写接口中所有的抽象方法
如果实现类没有重写所有的抽象方法,那么这个实现类自己必须是一个抽象类
接口中的默认方法,可以通过接口实现类对象直接调用,也可以被实现类对象覆盖重写
*/
class MyInterfaceAbstractImpl implements MyInterfaceAbstract {
@Override
public void method1() {
System.out.println("方法一");
}
@Override
public void method2() {
System.out.println("方法二");
}
@Override
public void method3() {
System.out.println("方法三");
}
@Override
public void method4() {
System.out.println("方法四");
}
/*
@Override
public void methodDefault() {
System.out.println("重写的默认方法");
}
*/
}
public class DemoInterface {
public static void main(String[] args) {
MyInterfaceAbstractImpl impl = new MyInterfaceAbstractImpl();
impl.method1();
impl.method2();
impl.methodDefault();
}
}
接口中的静态方法
/*
接口中的静态方法不能通过实现类的对象来调用,只能通过接口名称直接调用
*/
interface Interface {
static void methodStatic(){
System.out.println("接口中的静态方法");
}
}
class InterfaceImpl implements Interface {
}
public class DemoInterface1 {
public static void main(String[] args) {
InterfaceImpl impl = new InterfaceImpl();
//错误写法
//impl.methodStatic();
//正确写法
Interface.methodStatic();
}
}
接口中私有方法和常量
/*
接口中的私有方法:
问题描述:
我们需要抽取一个公共方法,用来解决两个默认方法的代码重复问题。
但这个方法不应该让实现类使用,应该是接口内私有化的。
解决方法:
1.普通私有方法:解决多个默认方法之间代码重复问题
2.静态私有方法:解决多个静态方法之间代码重复问题
*/
/*
接口中的常量:
接口中可以定义成员变量,但有public static final 三个关键字进行默认修饰(可以省略不写),
从效果上看,这其实是接口的“常量”。且必须进行明确地赋值。
常量名称使用完全大写字母,中间用下划线分隔(推荐写法)。
*/
interface Interface2 {
public static final int NUM_OF_CLASS = 10;
default void method1(){
System.out.println("一");
methodCommon();
}
default void method2(){
System.out.println("二");
methodCommon();
}
//普通私有方法
private void methodCommon(){
System.out.println("一二");
}
static void methodSta1(){
System.out.println("static1");
methodStaticCommon();
}
static void methodSta2(){
System.out.println("static2");
methodStaticCommon();
}
//静态私有方法
private static void methodStaticCommon(){
System.out.println("static12");
}
}
class InterfaceImpl2 implements Interface2 {
}
public class DemoInterface2 {
public static void main(String[] args) {
InterfaceImpl2 impl = new InterfaceImpl2();
impl.method2();
Interface2.methodSta1();
System.out.println(Interface2.NUM_OF_CLASS);
}
}
接口注意事项
/*
接口的注意事项:
1.接口没有静态代码
2.接口没有构造方法
3.一个类只能有一个直接父类,但可以有多个接口
public class MyInterfaceImpl implements InterfaceA, InterfaceB {
//覆盖重写所有的抽象方法
}
4.实现类的多个接口中存在重复抽象方法,只需覆盖重写一次
5.如果没有全部重写抽象方法,实现类就必须是一个抽象类
6.实现类的多个接口存在重复的默认方法,一定要对此方法进行重写
7.一个类的直接父类中的方法和接口中的默认方法冲突,优先使用父类中的方法
8.一个接口可以多继承
public Interface MyInterface extends InterfaceA, InterfaceB{}
*/
多态(multi)
/*
多态性:父类引用子类对象(向上转型)
格式:
父类名称 对象名 = new 子类名称();
接口名称 对象名 = new 实现类名称();
*/
public class DemoMulti {
public static void main(String[] args) {
Fu obj = new Zi();
obj.method(); //成员方法看new的是谁,输出“子类方法”
obj.methodFu(); //"父类特有方法"
System.out.println(obj.num); //成员变量看等号左边是谁,输出“10”
}
}
class Fu {
int num = 10;
void method(){
System.out.println("父类方法");
}
void methodFu(){
System.out.println("父类特有方法");
}
}
class Zi extends Fu {
int num = 20;
void method(){
System.out.println("子类方法");
}
}
多态的向下转型与instanceof
/*
多态的向下转型:
其实是一个还原动作,当子类需要访问自己独有的成员方法时,需要向下还原为子类类型
格式:
子类名称 对象名 = (子类名称) 父类对象
举个例子:
Animal ani = new Cat(); //本来是猫,向上转型为动物
Cat cat = (Cat) ani; //本来是猫,已经被当成是动物,还原回猫
向下转型时有时会不确定父类对象对应哪一子类,解决方法:
instanceof
例子:
public void giveMeAPet (Animal ani) {
if(ani instanceof Dog) {
Dog dog = (Dog) ani;
dog.watchHouse()
}
if(ani instanceof Cat) {
Cat cat = (Cat) ani;
cat.catchMouse()
}
}
*/
内部类
/*
成员内部类:
1.间接方式:在外部类的方法中使用内部类,然后再main中调用外部类方法
2.直接方式:外部类名称.内部类名称 对象名 = new 外部类名称().new 内部类名称()
局部内部类:
在成员方法中定义类,创建对象等对内部类的一系列操作。main中只调用该成员方法
*/
/*
内部类访问外部类重名变量:
外部类名称.this.重名变量名称
*/
//外部类
class Body {
int num = 10;
//成员内部类
public class Heart {
public void methodHeart(){
System.out.println("成员内部类方法");
}
int num = 20;
public void methodNum(){
int num = 30;
System.out.println(num); //30
System.out.println(this.num); //20
System.out.println(Body.this.num); //10
}
}
public void methodOuter(){
//局部内部类
class Inner {
int num = 10;
public void methodInner() {
System.out.println(num);
}
}
Inner inner = new Inner();
inner.methodInner();
}
public void methodBody() {
System.out.println("外部类方法");
}
public void bodyHeart() {
Heart heart = new Heart();
heart.methodHeart();
}
}
public class DemoInnerClass {
public static void main(String[] args) {
//间接方法
Body body = new Body();
body.bodyHeart();
body.methodOuter();
//直接方法
Body.Heart heart = new Body().new Heart();
heart.methodHeart();
heart.methodNum();
}
}
匿名内部类
/*
使用场景:如果接口的实现类(或者父类的子类)只需要使用唯一一次
那么这种情况就可以省略掉该类的定义,而改为使用【匿名内部类】
注意:
1.匿名内部类在创建对象的时候,只能使用唯一一次,如果需要多次创建对象
且内容一样的话,就必须使用单独定义的实现类了
*/
interface MyInterface {
public void method();
}
public class NImingInnerClass {
public static void main(String[] args) {
//匿名内部类
MyInterface obj = new MyInterface() {
@Override
public void method() {
System.out.println("匿名内部类实现了方法");
}
};
obj.method();
}
}
来源:CSDN
作者:SEHDY
链接:https://blog.csdn.net/weixin_42384816/article/details/104359133