JavaBasic_10

JVM中的对一个对象的所有初始化动作,是javac在字节码文件中帮我们生成的

1.成员变量的显式初始化

2.初始化代码块(构造代码块)

3.构造方法

初始化静态的东西


在Java中,一个没有方法体的方法应该定义为抽象方法,而如果一个类中含有抽象方法,则该类必须定义为一个抽象类


抽象方法和抽象类语法:

1.抽象类和抽象方法必须使用abstract(修饰符)声明

2.抽象方法不能有方法体(连定义方法的{}都没有)

3.抽象类不一定有抽象方法,但是含有抽象方法的类必定是抽象类

4.抽象类不能实例化(但是多态机制可以用子类实例化)

a.通过抽象类的子类来实例化子类

抽象类的子类(二选一)

1.如果不想重写抽象类里面的抽象方法,则子类必须是抽象类

2.如果不是抽象类,则必须实现抽象父类的所有抽象方法

方法覆盖的条件

1.方法签名必须完全一样

2.方法返回值类型,兼容(要么一样, 要么子类类型)

3.访问权限子类权限>=父类权限

==尤其注意,即使一个类中没有抽象方法,我们也可以将其定义为抽象类,因为有的时候,出于各种各样的原因,你不想让别人直接实例化你的类对象==。

抽象类不能被实例化,即不能使用抽象类的构造函数创建对象(java语法),抽象类中可以声明抽象方法,除此之外抽象类与一般的类没有区别。

1.抽象类只定义类的部分行为,这些行为是子类共有的(具体行为可以和抽象行为共存)

2.其他行为(抽象方法)由子类实现的抽象方法提供,因此抽象类通常作为一个框架

3.将子类将实现的抽象方法组织起来,简化或限制子类的设计

抽象类的成员特点:

1.抽象类的成员变量:既可以变量,又可以是常量(和普通类没有任何区别)

2.抽象类的构造方法(可以):用于子类访问父类数据的初始化

3.抽象类的方法:可以是抽象的,也可以是非抽象的,作用是:

抽象的:(从语法层面)强制子类实现       (类似的有枚举类型   PrameterizedType )

非抽象的:子类可以复用

public class Supplement02 {

    public static void main(String[] args) {
        // 抽象类本身不能被实例化
        //Animal animal = new Animal();
        //animal.shout(animal);

        // 抽象类不能被直接实例化
        // ctrl + 鼠标左键,点击代码产看源代码
        //TestAbstractClass testAbstractClass = new TestAbstractClass();
    }

}

//class Animal {
//
//    public void shout() {
//
//    }
//}

//class Dog extends Animal{
//    public void shout() {
////      System.out.println("dog shout");
//        shout();
//    }
//}

abstract class TestAbstractClass{

    public void test() {
    }
}

abstract class Creature {

    int i;
    int j;

    public Creature() {
    }

    public Creature(int i, int j) {
        this.i = i;
        this.j = j;
    }

}

//抽象累的子类,不一定必须实现父类中的所有抽象方法,
// 假如抽象类的子类没有实现父类所有的抽象方法,将该子类定义为抽象方法
abstract class Animal extends Creature{
    int height;
    int weight;
    int age;
    public Animal(int height, int weight, int age, int i, int j) {
        super(i, j);    //各司其职,做好自己本类的事
        this.height = height;
        this.weight = weight;
        this.age = age;
    }
   public abstract void shout(Animal a);

   public Animal testOverride() {
       return null;
   }

}

abstract class TestAbstractClass{

    public void test() {
    }
}

class Cat extends Animal {
    int k;
    public Cat(int height, int weight, int age, int i, int j, int k) {
        super(height, weight, age, i, j);
        this.k = k;
    }

    public  void shout(Animal a){
        System.out.println("cat shout");

    }

    public void go() {

    }

    @Override
    public Cat testOverride() {
        return null;
    }
}

接口

什么是接口

一个完全抽象的类,所有的方法都是抽象方法(只存在抽象方法,jdk之前)

接口的使用场景:

通常使用接口来声明,存在这样一些行为,某些不是被所有子类所共有的行为,而是一些特殊群体所共有的行为,使用接口来组织这些抽象行为

实现接口,其实相当于表示的是一个实质上的继承关系

class A implements 接口B 接口B 和 A他们之间是继承关系

public class InterfaceDemo1 {
}

//抽象类Animal
abstract class Animal {
    public abstract void shout();

}

//抽象类SpecialBehavior
abstract class SpecialBehavior {

    public abstract void arithmetic();

    public abstract void go();
}

//接口InterfaceSpecialBehavior
interface InterfaceSpecialBehavior {
    public abstract void arithmetic();

    public abstract void go();
}

//Cat类继承父类Animal
class Cat extends Animal {

    @Override
    public void shout() {
        System.out.println("cat shout");
    }
}

// 在java中,对于同一个类,只能声明该类继承自一个类,但是在java中同一个类可以实现多个接口
class SpecialCat extends Animal implements InterfaceSpecialBehavior{

    @Override
    public void shout() {

    }

    @Override
    public void arithmetic() {

    }

    @Override
    public void go() {

    }
}

接口使用Interface 关键字进行声明(类使用class关键字声明)

格式:interface 接口名{   }

类实现接口使用implements 关键字

格式: class 类名 implements 接口名{ }

接口中是否必须包含抽象方法呢?不一定,比如:空接口

类A implemets 接口B 类A和接口B是继承关系 类A(“继承”)实现接口B

空接口通常被当成是一种标记,比如Serriallizable接口就是一个空接口

if(对象 instanceof 空接口类型){

}

接口无法直接实例化

如何实例化?由其具体的子类实例化

new 接口类型的对象 但是我们new 接口的实现类(接口的子类)

接口的子类(普通类):

1.要么是抽象类(接口的实现类没有实现接口中定义的所有抽象方法)

2.要么重写接口中所有的抽象方法(子类变成一个普通类,从而该普通类可以被实例化)

关系

接口和接口的关系:(继承)

1.接口之间可以相互继承,即可以定义一个接口用extends关键字去继承一个已有的接口

普通类和接口的关系:(实现)

2.可以定义一个类用implements关键字去实现一个接口中的所有方法

抽象类和接口的关系(实现)

可以去定义一个抽象类用implements关键字去实现一个接口中定义的部分方法。

类与类、类与接口的关系:

一个类可以继承一个父类的同时,实现一个或多个接口,extends关键字必须位于implements关键字之前

import java.io.BufferedOutputStream;
import java.io.Serializable;

public class InterfaceDemo2 {

    public static void main(String[] args) {
    }
}

//空接口  接口中不一定一定包含抽象方法
interface InterfaceDeination {

}

// 接口的使用:通过implents关键字,使用定义好的接口,声明某个类实现该接口
class A implements InterfaceDeination{

}

interface InterfaceNotNull{

    //包含抽象方法
    public abstract void testInterface();

    public abstract void  eat();
}

//接口子类的第二种情况:子类为普通类
class SonOfInterNotNull implements InterfaceNotNull{

    @Override
    public void testInterface() {

    }

    @Override
    public void eat() {

    }
}

//接口子类的第1中情况,子类为抽象类
abstract class  SonOfInterNotNull2 implements InterfaceNotNull {

    @Override
    public void testInterface() {

    }
}

class  Father {

    public void beat() {

        System.out.println("father beat");
    }

}

// 一个类可以在继承另一个类的同时,实现多个接口
class Son extends Father implements InterfaceDeination,InterfaceNotNull  {

    @Override
    public void testInterface() {

    }

    @Override
    public void eat() {
    }
}

单亲继承和双亲继承

Java语言中,类(class)只支持单继承,一个类只能有唯一的(直接)父亲

从语法上来看,一个类的声明中,extends关键字之后只能跟一个类名,否则报错:class cannot extends multi class

单重继承,并不意味着某个类各类就只能继承一个类的代码,可以间接继承多个类的代码。

在Java语言中,接口(Interface)可支持多亲继承 ,一个接口可以有多个父接口,子接口拥有所有父接口中声明的方法

1.接口之间有多重继承

public class JavaFrameExtends {
    public static void main(String[] args) {

    }
}

class GrandFather {

}

class Father1 extends GrandFather{

}

// 这种继承形式才叫多重继承,Java不支持
//class Father2 extends GrandFather, Object{
//
//}

//通过加深继承层次,间接继承多各类的代码
class Son1 extends Father1 {

}

interface FirstInterface {

    public abstract void first();
}

interface SecondInterface{
    public abstract void second();
}

// 接口确实实现了真正的多重继承
interface  ThirdInterface extends FirstInterface,SecondInterface{

}

class  TestInterfaceMultiExtends implements ThirdInterface {

    @Override
    public void first() {

    }

    @Override
    public void second() {

    }
}

interface FourthInterface {

}

// 对于普通类来讲,也可以实现多重继承
class  ClassMultiExtends extends TestInterfaceMultiExtends implements FourthInterface {

}

在普通类中,java也声称实现了多重继承,如果把实现接口当做是一种继承,那么因为一个普通类,可以在继承一个类的同时,实现一个或多个接口,从这个角度来理解,普通类实现了多重继承(并非真正意义上的多重继承)

但是以上对普通类的多重继承的说明,只针对jdk1.8之前,在jdk1.8中接口中新增了两种方法:

1.默认方法

2.静态方法 (当你要定义工具方法的时候,通常如果是某接口的实现类都需要的,那么就可以在接口中定义静态方法)

这两种方法在接口中,都是可以有方法实现的。

1.在接口中,如果要访问静态方法,如果只通过方法名.来访问的话,只能在定义默认方法的接口中

2.如果使用接口名.的形式来访问静态方法,静态方法在哪里都可以访问到

3.对于默认方法,在子类类体,或者子类对象名.的形式时都可以访问

public class InterfaceDome3 {
    public static void main(String[] args) {
        AA aa = new AA();
        aa.test();
        aa.testDefault();

    }
}

interface  NewMethods {
    //默认方法
    default void testDefault() {
        System.out.println("我是默认方法");
        //testStatic();
    }

    static void testStatic() {
        System.out.println("我是静态方法");
    }

    //public abstract void a();

    // 新添加的添加默认方法不会影响,已经实现过接口的类
    default void addDefault() {

    }

}

interface SonOfNewMethod extends NewMethods{

    // 覆盖默认方法, 在子类中不仅可以覆盖,而且还可以把默认方法覆盖成抽象方法
    @Override
     void testDefault();
}

class AA implements NewMethods{

    public void test() {
        testDefault();
       // testStatic();
        NewMethods.testStatic();
    }
}

public class HomeWork04 {

    public static void main(String[] args) {
        A a = new A();
        //访问接口的默认方法1—在子类的成员方法中调用
        a.test();
        //访问接口的默认方法2—在实例化子类对象中用 子类对象名.的形式访问
        a.testDefault();
        //访问静态方法1:在任何地方使用 接口名.静态方法名 调用
        Test.testStatic();
    }
}

interface Test {

    //默认方法
    default void testDefault() {
        System.out.println("我是默认方法");
        //访问静态方法2:在默认方法中调用静态方法
        testStatic();
    }

    //静态方法
    static void testStatic() {
        System.out.println("我是静态方法");
    }
}

class A implements Test {

    public void test() {
        testDefault();
    }
}

接口中可以声明以下成员:

(1)成员

(2)方法

注意事项:

1.接口中的成员都是public的,不能指定其他的访问控制修饰符

2.接口中的成员变量默认是static final,必须显式初始化,接口中的方法只能提供方法头声明,不能提供实现,且除abstract外,不能使用其他修饰符。

3.接口中的成员变量默认是static final,必须显式初始化

4.接口中的方法只能提供方法头声明,不能提供实现,且除abstract外,不能使用其他修饰符(jdk 8之前)

方法的默认修饰符:   public abstract修饰

在接口中,如果不给方法添加访问权限修饰符,那么接口中默认的访问权限全都是public,编译器在字节码文件中会添加public

子接口的域将隐藏父接口中声明的同名域,被隐藏的父接口中的域必须通过父接口名访问

要访问被隐藏的域:父接口名.  访问被隐藏的父接口中的同名域

在接口中也存在着方法的重载和覆盖

在jdk1.8之前接口中的方法覆盖没啥意义是因为接口中不提供方法的实现,但是jdk1.8之后,因为接口新增了了默认方法,该方法有方法可以实现,jdk1.8之后接口中覆盖是有意义的

interface [extend,]

{

[public static final]   数据类型 常量名=常量值;

[public abstract]   返回类型 方法名(参数列表);

}

通过接口可以实现不相关类的相同行为,而不需考虑这些类之间的层次关系

1.完全不同的类可以实现同一个接口(同一个实现同一个接口之后,就可以被看成同一个接口类型)

2.接口实现,不受java中单重继承的限制

接口可以继承多个接口,但不能继承类

public class InterfaceDemo4 {
    public static void main(String[] args) {
        Interface2.testInterfaceField();
    }
}

interface  Interface1 {

    //private int add();  不行
      int add();        //不行
    //protected int add();不行
    //public int add();

    // 接口中不能定义构造代码块
//    {
//    }

    // 接口中不能定义静态代码块
//    static {
//    }

    // 接口中的成员变量默认被static final修饰
    int i = 0;
}

interface  Interface2 extends Interface1{

    int i = 100;

    static void testInterfaceField() {
        System.out.println(i);
        System.out.println("父接口中的i值: " + Interface1.i);

    }

    //接口中的抽象方法也可以重载
    int add(int a, int b);
    int add(int a, int b, int c);

}

class SonOfInterface1 implements Interface1{
    @Override
     public int add() {
        return 0;
    }
}

//class SuperSon extends SonOfInterface1 implements Interface2{
//
//}

接口的实现与接口特点

具体类实现一个接口就是要实现该接口的所有方法(抽象类除外)

接口中方法都是抽象的

多个无关的二类


内部类

把类定义在其他类的内部,这个类就被称为内部类

内部类的访问特点:

1.内部类可以直接访问外部类的成员,包括私有。

2.外部类要访问内部类的成员,必须创建对象

public class InnerClassDome1 {

    public static void main(String[] args) {
        //在外部类中,我们可以通过创建内部类对象,来访问内部类的成员变量
        OuterClass outerClass = new OuterClass();
        outerClass.accInnerClassField();
    }

}

class OuterClass {
    //外部类的私有成员变量
    private int i;

    public void accInnerClassField() {

        FirstInnerClass firstInnerClass = new FirstInnerClass();
        System.out.println(firstInnerClass.j);
    }

    //定义在其他类内部的类就叫做内部类
    public class FirstInnerClass{

        //内部类中的private不影响定义它的外部类对其成员变量的访问
        private int j = 100;
        public void accOuterPrivateField() {
            System.out.println(i);
        }
    }
}

假设,某pc公司最新最新研制了一款pc,在这个pc,中包含了该公司最高成果,当前全球最厉害的cpu

假设我们用一个类来表示pc,那么同过我们之前学习的知识是无法完成这个需求的:

因为我们如果使用普通类,一旦把普通类的成员 变量的访问权限定义成private,虽然别人访问不到cpu中的成员,但同时,我们自己也访问不到cpu 中的成员

但是如果使用内部类,利用内部类的访问特征:

1.内部类可以直接访问外部类中的成员变量包括私有。(cpu 内存更方便的交互)

2.内部类中可以创建对象的方式,访问内部类成员(包括私有) (我们Pc类,但别的类就访问不了Cpu中的成员)

public class InnerClassSituatation {
}

class PC {
   Cpu cpu;
   Memoery mem;

   public PC(Cpu cpu) {
      this.cpu = cpu;
   }

   public double calculate() {
       Cpu cpu = new Cpu();
       return 0.0;
   }

   private class Cpu{
        private int core;
        private int hz;

        private double calculate() {
            //cpu的执行流程,制作工艺
            return 0.0;
        }
    }

}

class Memoery {

}

内部类位置

按照内部类在类中定义的位置不同,可以分为如下两种格式:

内部类首先可以被看成是外部类的成员,

1.成员位置(内部成员类):类中其他成员外

2.局部位置(局部内部类):类中方法之内

成员位置内部类:

1.在外部类中如何访问呢?通过普通的创建对象的方式

2.在外部类的外部如何访问内部类?

外部类名.内部类名 对象名= 外部对象.内部类对象

内部成员的常见修饰符

1.private 为了保证数据的安全性

2.static 为了让数据访问更方便

被静态修饰的成员内部类只能外部类的静态成员

内部类被静态修饰后的方法

非静态方法:外部类名.内部类名 对象名 = new 外部类名.内部类名();

静态方法:上面创建的对象访问,或者, 外部类名.内部类名.方法名();

public class ClassifyInnerClass {

    // 这个类就是外部类的外部
    public static void main(String[] args) {
        Outer1 outer1 = new Outer1();
        outer1.accPrint();

        //在外部类的外部,创建内部类对象
        //1. 因为,我们定义的内部类,是外部类的一个成员
        //2. 成员依赖于对象而存在,即内部类对象依赖于外部类对象而存在
        //3. 所以要得到一个内部类对象,必须先创建外部类对象,在外部类对象上,调用创建对象的表达式
        //   创建对象的表达式: new 类型(..)
        Outer1 outer11 = new Outer1();

        //接收内部类对象的引用变量的类型用 外部类.内部类的形式来表示
        //Outer1.Inner1 inner1 = outer11.new Inner1();

        //当内部类被static修饰符所修饰
        Outer1.Inner1 inner12 = new Outer1.Inner1();
    }
}

 class Outer1 {

    int  i = 100;
    int j = 1000;

    public void accInner() {
        System.out.println(i);

        //在外部类的成员方法中,访问内部类的静态成员方法
        Inner1.testStatic();

    }

    public void accPrint() {
        //在外部类中访问内部类
        Inner1 inner1 = new Inner1();
        inner1.accOuterMethod();
    }

    //private class Inner1
    static class Inner1{

        int i = 1000;

        //内部类还可以直接访问外部类的成员方法
        public void accOuterMethod() {

//            accInner();
//            System.out.println(j);
        }

        public static void testStatic() {

        }
    }
}
上一篇:POJ 3621 Sightseeing Cows 【01分数规划+spfa判正环】


下一篇:window.showModalDialog返回值和window.open返回值实例详解