面向对象基本的基本理解
一个具体的对象基本有两种特征:对象有什么和对象能做什么。
对象有什么称为属性,对象能做什么称为方法。
一切客观存在的事物都是对象,万物皆对象...
提取某些对相同或者相似的属性和行为,归结出的抽象定义,称为:类
1.类是相同或者相似的对象的一个模板,它描述一类对象的行为和状态
2.类是具有相同属性和方法(行为)的对象的集合
类
Java是面向对象的语言,其一就体现在Java程序都是以类class为组织单元。
定义一个class主要分为3步:
1.定义类名
2.编写类的属性(也可不定义)
3.编写类的方法(也可不定义)
一个类可以包含以下类型变量:
1.局部变量:在方法,构造方法,语句块中定义的变量,用完销毁
2.成员变量:定义在类中,方法体之外的变量。这种变量在创建对象时初始化
3.类变量:也叫静态变量,类变量也声明在类中,方法体之外,但必须声明为 static
类型,静态变量随类的加载产生,与对象无关。
类的创建语法: 类名 对象名 = new 类名();
类可以看做是我们自己创建的数据类型,定义类时不会在内存中开辟空间,实例化时才会
对象
成员变量与局部变量
成员变量:
1.在类中,方法外定义,本类可用,也可被与本类相关的其他类使用
2.作用域本类可见
局部变量:
1.只能在所定义的方法中使用
成员变量与局部变量同名共存时,局部变量有优先级
对象的创建过程
1.new类名触发对象创建 2.在内存中开辟对象空间 3.为各个属性赋予初始值 4.执行构造方法中的代码 5.[将对象的地址赋值给变量]
类对象内存分析图
构造方法
作用
用于在开发过程中创建对象使用,创建对象目前的格式 new 类名(有可能使用到的参数); 类名(有可能使用到的参数); 这就是构造方法 Constructor 构造方法可以初始化当前创建对象中的成员变量数据!!!
格式
格式: public 类名(所需初始化参数列表) { 初始化语句; } 细节: 1. 构造方法的名字必须是类名,并且其他方法的名字不能是类名 2. 构造方法没有返回值类型声明 3. 初始化参数列表和正常的方法列表操作使用一致 4. 初始化语句,大多数是都是一些赋值语句
要求
格式: public 类名(所需初始化参数列表) { 初始化语句; } 注意: 如果在代码中程序员自行完成了构造方法,Java编译器不再提供自动生成的无参数构造方法。 【强制要求】 以后代码中无论什么时候都要给用户提供一个无参数构造方法使用
构造方法执行顺序
总结
构造方法功能是用于初始化创建对象的成员变量数据 构造方法是一个方法,参数使用方式和方法一致 2. 构造方法选择 Java编译器会根据构造方法中的【参数类型,个数,顺序】来做选择,如果没有指定的构造方法,报错!!! 3. 无论什么时候一定要给当前类提供一个无参数构造方法。 4. 【以下代码报错】 Dog(String name); Dog(String color); 调用: String color = "red"; Dog dog = new Dog(color); 在Java代码中不允许出现相同数据类型,个数,顺序的构造方法,和参数名没有关系,Java编译器选择过程中,有且只针对数据类型,个数,顺序选择,参数名真的无所谓。
无参构造
有参构造//构建有参构造方法时,要求提供参数,但是不使用参数会怎样?==>没有任何影响
只有未提供构造方法时,系统才会默认提供无参构造方法;只要提供了,系统就不会再提供无参构造方法
static
static可以修饰属性,方法,代码块
静态成员
static修饰的成员为静态成员或者类成员,属于整个类所有,而不是某个对象所有,即被类的所有对象所共享。静态成员可以使用类名直接访问,也可以使用对象名进行访问(推荐使用类名访问,静态成员与对象的产生和消失没有关系,使用对象名访问时虚拟机会自动转为类名访问)
实例属性:每个对象单独分别持有,单方面修改不会影响其他对象
静态属性(类属性):类只有一份,所有对象共有,任何对象修改均会影响其属性
static属性在方法区存在
public class StaticTest{ public static String string="shiyanlou"; public static void main(String[] args){ //静态成员不需要实例化 直接就可以访问 System.out.println(StaticTest.string); //如果不加static关键字 需要这样访问 StaticTest staticTest=new StaticTest(); System.out.println(staticTest.string); //如果加上static关键字,上面的两种方法都可以使用 } }
static使用要点:
static使用要点: 1.static修饰的方法是静态方法,静态方法不依赖于对象,无需创建对象就可以通过类名调用 2.static修饰的成员是静态成员,静态成员不依赖于对象,无需创建对象就可以通过类名调用 3.static方法不能访问非静态成员变量和非静态方法,但是非静态成员变量和非静态方法可以访问静态方法 4.由于不被实例化也可以调用,所有不能有this,super 5.静态方法可以继承,不能重写,没有多态(使用@Override注解也会报错) 6.静态代码块在类加载时被执行,且只执行一次
7.上述要点的部分原因是:I:时间上:static在类被加载时就会执行,static语句执行时可能对象还未创建 II:空间上:一个类会创建多个对象,静态方法访非静态属性时,不能确认是访问的哪一个对象。((mc.b)会自动转换成(类名.b))
//Arrays.copyOf();Array.sort();Math.random();
第7点图例
Java程序调用种类:
java程序调用有两种调用方式:
静态分派:静态分派中,允许参数列表不同的重名方法,指静态方法之间的重载
动态分派:在具有继承关系的情况下,调用实例方法时,自低向上的查找可用的方法版本,指方法的覆盖
方法调用的五个指令:jvm
1.innokespecial 私有方法,构造方法
2.invokeinterface 接口防范
3.invokestatic 静态防范
4.involkevirtual 虚方法(被子类覆盖的方法,抽象类)
5.invokedynamic 动态链接方法
【其他知识】
方法在本类中可以通过“方法名()”直接访问,在其他类中通过“类名.方法名()”访问
【问题】
final关键字
final可以修饰内容
1.修饰类:该类不允许继承,为最终类
2.修饰成员方法:则该方法不允许被覆盖(重写)
3.修饰局部变量:则该变量只能赋一次值,即常量;赋值时机:显示初始化
4.修饰成员变量:则该类的属性不会进行隐形初始化(类的初始化属性必须有值),在构造方法结束前赋值:显示初始化,动态代码块,构造方法中
6.修饰静态变量:加载完成前赋值:显示初始化,静态代码块
7.修饰基本数据类型:值不可变
8.修饰引用数据类型:地址不可变
代码实现
/* final关键字可以修饰 局部变量 有且只能被赋值一次,赋值之后不可以修改 成员变量 定义时必须初始化,未初始化报错 成员方法 使用final修饰的方法为最终方法,不能被重写!!! 类 没有子类,不能被继承 Java中是存在一些类是使用final修饰的 String类 */ final class Father { final public void game() { System.out.println("黄金矿工!!!"); } } // The type Son cannot subclass the final class Father // Son类不能是final修饰的类Father类的子类,不能继承Father // class Son extends Father { // The blank final field age may not have been initialized // 使用final修饰的成员变量还没有被初始化 // final int age = 10; // Cannot override the final method from Father // 使用final修饰的方法为最终方法,不能被重写!!! // public void game() { // System.out.println("PUBG"); // } // } public class Demo1 { public static void main(String[] args) { final int num; num = 10; // The final local variable num may already have been assigned // 使用final修饰的局部变量num已经被赋值 // num = 20; } }
final修饰类
class Dog { String name; int age; } public class Demo2 { public static void main(String[] args) { Dog dog = new Dog(); dog.name = "八公"; dog.age = 15; /* * final修饰的是dog1,dog1是一个类对象,同时是一个引用数据类型的变量。 * dog1存储数据不可以改变!!!dog1指向不可以改变,但是dog1指向空间 * 中的内容可以改变。 * */ final Dog dog1 = new Dog(); // dog1能不能操作成员变量??? dog1.name = "骚杰"; dog1.age = 16; // 能不能修改??? dog1.name = "一杯二锅头"; dog1.age = 20; Dog dog2 = dog1; dog2 = new Dog(); // The final local variable dog1 cannot be assigned. // It must be blank and not using a compound assignment // dog1 = new Dog(); } }
类加载
JVM首次使用到某个类时,第二次用到不会加载。
java_home:系统需要的class文件
classpath:自己编写的class文件
加载时机:
1.创建父类对象
2.创建子类对象
3.访问静态属性
4.调用静态方法
5.Class.forName()主动加载一个类
静态代码块
动态代码块是写在类下面的"{}"的内容,动态代码块的执行地位由于构造方法
执行顺序:动态代码块作用小体现在没有特殊的执行顺序
创建对象==>执行构造方法(无父类)==>初始化属性==>动态代码块==>构造方法中代码
静态代码块是写在类下面,在动态代码块之前:static,静态内容是在类加载时触发,只执行一次。
静态属性,静态代码块这两项没有 执行先后顺序,谁在前谁先执行,一般将静态属性放在静态代码块之前。
继承关系下的执行顺序
创建对象==>父类静态属性==>父类静态代码块==>子类静态属性==>子类静态代码块==>父类实例属性==>父类实例代码块==>父类构造方法==>子类实例属性==>子类实例代码块==>子类构造方法
封装
封装:即隐藏对象的属性和实现细节,仅公开对外接口,控制在程序中属性的访问权限(包括读取和修改)
封装概述
封装:
归纳总结
提高重用度
降低使用难度,使用更方便
循环封装过程
方法封装功能
类封装数据
框架封装模块
一段代码使用了三遍,做成一个循环
一个循环使用了三遍,做成一个方法
一个方法使用了三遍,做成一个工具类
一个工具类使用了三遍,做成一个文档
一个文档使用了三遍,做成一篇博客
封装好处:
1.只能通过规定方式访问数据
2.隐藏类的实例细节,方便实现和修改
如何封装:
1.修改属性的可见性:设置修饰符为private 2.创建setXXX和getXXX方法,控制属性 3.在set和get方法中加入属性判断语句 4.创建有参无参构造方法
权限修饰符
private
私有化内容,使用private修饰的成员变量,成员方法和构造方法,有且只能类内使用,类外没有操作权限
使用private修饰的内容有且只能在class所处大括号以内使用
public
公开内容,只要存在对应的类对象,都可以通过类对象调用类内的public修饰的成员变量和成员方法
访问修饰符 | 本类 | 同包 | 子类 | 其他 |
private | OK | |||
默认 | OK | OK | ||
protected | OK | OK | OK | |
public | OK | OK | OK | OK |
封装解决私有化变量的取值赋值问题
private私有化修饰的成员变量,类外不能通过类对象操作,取值,赋值。 JavaBean规范规定了 setter ==> 赋值操作 格式: public void set成员变量名(对应成员变量数据类型参数) { 赋值操作; } getter ==> 取值操作 public 对应成员变量数据类型返回值 get成员变量名字() { return 成员变量; } 注意 1. 方法格式固定,setter和getter方法操作过程不能修改 2. 方法需要符合命名规范,小驼峰命名法 3. boolean类型数据较特殊 boolean类型的成员变量getter方法要求是is开头
this
this关键字在方法中可以区分成员变量和局部变量。
this主要有三类结构:
1. 当前类中的属性:this.属性
2. 当前类中的方法(普通方法,构造方法):this(),this.方法名称()
3. 当前对象:
/* * this关键字在一个构造方法,调用其他构造方法 * 注意事项: * 1. 不能通过this关键字调用当前所在构造方法,无穷递归!!!错误!!! * 2. this(实际参数); 根据实际参数的类型,个数和顺序来完成的 * 3. Constructor call must be the first statement in a constructor * 通过this关键字调用其他构造方法,必须在当前方法体的第一行!!! * 4. 能不能在一个构造方法中,通过this关键字,同时调用两个构造方法??? * 不能!!!因为构造方法调用必须在第一行,如果存在两个必然有一个在第二行,语法报错 * 5. 两个构造方法,能不能通过this关键字相互调用??? * 不允许,无穷递归!!! * 6. 规范化,统一化方法执行操作,提高代码的安全性和一致性!!! * 7. 构造方法相互调用时须留出程序出口
* 8.this() 只能是调用的就是构造方法,使用时必须放在【构造方法】的【第一行】 */
//Dog()的递归都统一汇总到了三参构造的方法上面
class Dog { private String name; private String color; private int age; public Dog() { this(null, null, 0); } public Dog(String name) { this(name, null, 0); } public Dog(String name, String color) { this(name, color, 0); } public Dog(String name, String color, int age) { this.name = name; this.color = color; this.age = age; } public void setName(String name) { this.name = name; } public String getName() { return name; } } public class Demo2 { }
继承
继承是类与类之间的衍生关系,父类更通用,子类更具体。
继承代码格式: 关键字: extends 格式: class A extends B { }
1. A类使用extends关键字继承B类:
2. A类是B类的一个子类,B类是A类的唯一父类 3. 继承之后,子类可以通过继承得到父类中非私有化成员变量,和非私有化成员方法 4. 继承之后,子类不可以通过继承得到父类中的私有化成员变量,和私有化成员方法。
5. 产生继承关系后,子类可以得到父类非私有属性和方法,同时也可以定义子类独有方法和属性 【Tips】:private修饰的内容有且只能在类内使用!!!
继承实例
// 定义父类 //包含public和private的属性、方法各一个 class Father { public int height; private int testPrivate; public void game() { System.out.println("钓鱼,象棋"); } private void privateMethod() { System.out.println("私有化方法"); } } /* * Son是Father的一个子类 * Father是Son的唯一父类 */ class Son extends Father { public int age; public void study() { System.out.println("子类好好学习,天天向上"); } } //主类 public class Demo { public static void main(String[] args) { // 创建一个Father类对象 Father father = new Father(); // 通过Father类的对象father,给内部成员变量赋值 father.height = 170; father.game(); System.out.println(father.height); System.out.println("---------"); // 创建子类对象Son Son son = new Son(); // son本身的属性和方法(成员变量,成员方法) son.age = 16; son.study(); // son通过继承而来的方法属性 son.height = 172; son.game(); // 父类的私有化属性无法继承 // - The field Father.testPrivate is not visible // son.testPrivate; 这是父类的私有属性 // The method privateMethod() from the type Father is not visible // son.privateMethod(); 父类的私有化属性 } }
继承实例2(构造方法)
子类对象创建过程中,在使用构造方法时,会默认调用父类的【无参数构造方法】。
父类的构造方法,不是在创建父类的对象,只是在初始化父类的成员变量空间
问题
setget方法可以继承吗?==>可以继承
子类可通过父类的setget方法获取父类的private变量?==>子类可通过getset方法隐式获得父类的private方法
如何避免?
/** * 测试类证明子类对象和父类对象中是同一个地址 * */ public class Test2 { public static void main(String[] args) { // 创建子类对象 SonTest sonTest = new SonTest(); // 通过setter设置父类的私有成员变量str sonTest.setStr("SubString"); System.out.println(sonTest.getStr()); } } /** * 示例父类 * */ class FatherTest { private String str; public FatherTest() { System.out.println("FatherTest():" + this); } public void setStr(String str) { this.str = str; } public String getStr() { return this.str; } } /** * 示例子类 */ class SonTest extends FatherTest { public SonTest() { System.out.println("SonTest():" + this); } }
//测试结果 FatherTest():com.qfedu.b.extendsDemo.SonTest@15db9742 SonTest():com.qfedu.b.extendsDemo.SonTest@15db9742 SubString
继承可以解决代码重复冗余的问题:
1.子类可以拥有父类除private以外的属性和方法
2.子类可以拥有自己的属性和方法
3.子类可以重写父类的方法
4.Java中子类是单继承,一个子类只有一个父类
【注意】Java实现多继承的一个办法是implements接口,但接口不能有非静态属性
不可继承要点:
1.构造方法只创建本类对象,不可继承;
2.private修饰的属性和方法不可继承
3.父子类不在同一个package包内,default修饰的属性和方法
问题点:
可访问就可继承吗?
匿名对象
匿名对象概述
Person person = new Person("骚杰", 66, '男'); Person 类名 person 对象名 new Person(...) 向内存的堆区申请空间,创建一个Person类对象使用的内存空间 匿名对象 没有名字的对象,没有对象名的对象 格式: new 构造方法(所需参数) 用途 1. 提高开发效率,隐形眼镜日抛,一次性筷子 匿名对象当前行使用之后,如果没有其他引用数据类型的变量保存其地址,直接销毁 2. 简化代码结构 3. 通过匿名对象直接调用成员方法 4. 使用匿名对象作为方法的参数
代码演示:
package com.qfedu.a.computer2; public class Demo { public static void main(String[] args) { PC pc = new PC(new Screen("京东方",26.8F), new Keyboard("杂牌",84));//直接使用匿名对象将相关参数传入 pc.show(); System.out.println("--------------"); // 换键盘 pc.setKeyboard(new Keyboard("机械键盘",84));
System.out.println(pc.getKeyboard().getName());// 通过“.”的方式可以得到匿名对象的值
pc.show(); System.out.println("--------------"); //换显示器 pc.setScreen(new Screen("杂牌", 28.8F)); pc.show(); System.out.println("--------------"); } }
//Keyboard,Screen,PC 等其他类代码略
匿名对象总结
1. 匿名对象是为了提供开发效率,节约内存使用,同时让代码更加贴近于真实操作 2. 匿名对象常用方式 第一个是直接使用匿名对象调用成员方法 第二个是直接使用匿名对象作为方法的参数 3. 匿名对象【禁止】使用成员变量
super0501
1. super关键字可以用于在子类和父类之间,同名成员变量,同名成员方法调用时明确区分。 2. super关键字可以显式调用父类的构造方法,用于初始化父类的成员变量数据。 3. super关键字使用的格式,规范和this非常类似。
4. 当子类和父类之间存在相同属性名称或者方法时,存在属性遮蔽,方法覆盖现象,可用super区分
代码演示
class Father { public String name; public String age; public void game() { System.out.println("黄金矿工"); } } class Son extends Father { public String name; public String age; @Override public void game() { System.out.println("PUBG"); } public void test() { // 调用子类的成员方法,就近元素 game(); // super关键字调用父类的game方法 super.game(); // 调用子类成员变量 name = "大头儿子"; // super关键字调用父类的成员变量 super.name = "隔壁老王"; } } public class Demo1 { }
继承关系下的对象创建过程
在具有继承关系下的对象创建过程中,创建子类时会先创建父类对象。由父类的共性内容,加上子类的独有内容构成完整对象 super()表示调用父类对象,隐式存在构造方法首行 问题: super隐式存在首行和this显示存在时,执行谁?==>执行this 写了this()时,super的隐式存在无效
super,this访问子类,父类变量
继承中的对象创建
super关键字调用构造方法
/* * super关键字在子类构造方法中,调用父类构造方法 * 格式: * super(实际参数); * 会根据实际参数来选择使用父类对应数据类型,个数,顺序的构造方法,用于初始化父类的 * 成员变量数据。 * * 注意事项: * 1. 在没有指定选择哪一个父类构造构造方法,作为子类初始化父类成员变量空间的操作时 * Java编译器会默认选择父类的无参数构造方法。 * 2. 选择使用父类的有参数构造方法,初始化父类成员变量空间 * 3. 父类数据的交给父类的构造方法操作,不要在子类中操作。 * 4. super关键字显式调用父类的构造方法,必须在代码的第一行 * 5. super关键字调用构造方法,和this关键字调用构造方法,是否能共存??? * 【显式】情况下不可以!!! * 但是省略通过super关键字调用父类构造方法的情况下,Java编译器会在 * 编译的过程中,默认选择无参数父类构造方法使用 */ class Animal { private String name; public Animal() { System.out.println("Animal无参数构造方法"); } public Animal(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } } class Cat extends Animal { private String color; public Cat() { System.out.println("Cat无参数构造方法"); } public Cat(String color) { this(); this.color = color; System.out.println("Cat有参数构造方法"); } public Cat(String color, String name) { super(name); this.color = color; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } } public class Demo2 { public static void main(String[] args) { Cat cat = new Cat("玳瑁猫"); } }
方法重载【 】与重写【
方法重载:
是指在【同一个类】中定义多个同名方法。【参数类型,数量,顺序不能一致,方法重载和修饰符,返回值无关】
方法重载一般用于功能相似但是参数不同的方法里。(返回值,修饰符等可以不一样,但是尽量一样)
重载能够解决的问题
1. 简化代码结构,在同一个类内同名方法功能一致,但是参数满足多样化 2. 简化程序员的开发压力 3. 能够做到统一化处理方式
//方法重载案例
class Person { public void game() { System.out.println("大吉大利,今晚吃鸡"); } public void game(String name) { System.out.println("玩" + name); } public int game(String name, int time) { System.out.println("玩" + time + "个小时" + name); return 1; } } public class Demo1 { public static void main(String[] args) { Person person = new Person(); person.game(); person.game("LOL"); person.game("WOT", 2); } }
方法重写:
前提条件 1. 重写是存在与继承中子类,或者【遵从中的实现类】 2. 重写情况下要求子类中的方法和父类中的方法,方法声明完全一致 3. 方法体按照子类的情况来完成 注意事项 1. 子类重写父类方法,要求必须加上@Override严格格式检查 2. @Override会检查子类重写的方法,方法声明是否和父类一致
3. 子类覆盖父类方法后,调用子类方法时优先执行子类方法
问题
1.重写时如果方法与父类语法不一致会怎样?==>会生成子类的特有方法
多态(dynamic binding)
多态可分为:
方法的多态:重写,重载
对象的多态:对象向上转型,对象向下转型
多态是不同类的对象对同一消息做出的响应,即同一消息可根据不同的发送对象而采用多种不同的行为方式。
要理解多态必须要明白什么是"向上转型",比如,一段代码如下,Dog 类是 Animal 类的子类:
Animal a = new Animal(); //a是父类的引用指向的是本类的对象
Animal b = new Dog(); //b是父类的引用指向的是子类的对象
在这里,可以认为由于 Dog 继承于 Animal,所以 Dog 可以自动向上转型为 Animal,所以
b
是可以指向 Dog 实例对象的。
如果定义了指向子类的父类引用类型,那么它除了引用父类定义的属性和方法外,它还可以调用子类功能。但是对于只存在子类的方法和属性就不能获取。
class Animal { //父类方法 public void bark() { System.out.println("动物叫!"); } } class Dog extends Animal { //子类重写父类的bark方法 public void bark() { System.out.println("汪、汪、汪!"); } //子类自己的方法 public void dogType() { System.out.println("这是什么品种的狗?"); } } public class Test { public static void main(String[] args) { Animal a = new Animal(); Animal b = new Dog(); Dog d = new Dog(); a.bark(); b.bark(); //b.dogType(); //b.dogType()编译不通过 d.bark(); d.dogType(); } }
在这里,由于 b
是父类的引用,指向子类的对象,因此不能获取子类的方法(dogType()
方法), 同时当调用 bark()
方法时,由于子类重写了父类的 bark()
方法,所以调用子类中的 bark()
方法。
因此,向上转型,在运行时,会遗忘子类对象中与父类对象中不同的方法,也会覆盖与父类中相同的方法——重写(方法名,参数都相同)。
向上转型
概念:父类引用指向子类对象
作用:屏蔽子类间差距;灵活,耦合性低
多态中的方法覆盖:实际运行中,如果子类覆盖了父类的方法,则执行子类的方法。
多态的应用场景:
场景一: 使用父类作为方法形参实现多态,使方法参数的类型更为宽泛 调用方法时,可传递的实参类型包括:本类型对象+其所有的子类对象 场景二: 使用父类作为方法返回值实现多态,使方法可以返回子类对象 调用方法后,可得到的结果类型包括:本类型对象+其所有的子类对象
抽象类
在定义类时,使用abstrac关键字修饰的类叫抽象类,abstract修饰的方法,子类必须重写
抽象类不能new对象,但是可以声明引用
抽象类中有抽象方法,这种方法时不要完整的,仅有声明而没有方法体。
语法格式:
abstract void f(); //f()方法是抽象方法
语法特征
1. abstract修饰的方法 没有方法体 2. abstract修饰的方法,要求定义在abstract修饰的类内,或者接口interface内 3. abstract修饰的类,你认为有没有类对象??? abstract修饰的类内,是有可能存在abstract修饰的方法,而abstract修饰的方法是没有方法体的,如果能够得到一个abstract修饰类的对象,通过对象如何调用这些没有方法体的abstract方法。 4. abstract修饰的类,然后呢类内没有任何的一个abstract修饰的方法,请问有意义吗? 毫无意义!!!
代码实现
/** * LOL英雄类,每一个英雄都有QWER技能 * * @author Anonymous */ /* * 第一步: * 使用abstract关键字修饰要求子类重写的方法 * 【方法报错】 * Abstract methods do not specify a body * abstract修饰的方法没有方法体 * 【Eclipse快速修复】 * Ctrl + 1 * 选择 Remove Method Body 删除方法体 * * 第二步: * 【方法报错】 * The abstract method q in type LOLHero can only be defined by an abstract class * LOLHero类内的abstract修饰方法q(),有且只能定义在一个abstract修饰的类内 * 【类名报错】 * The type LOLHero must be an abstract class to define abstract methods * LOLHero类必须是一个abstract类,才可以定义abstract方法 * 【语法要求】 * abstract修饰的方法,必须在定义在abstract修饰的类内或者XXXXXXXXXXXXXXXXXXXXXXXXX * 【Eclipse快速修复】 * Ctrl + 1 * 选择 Make Type 'LOLHero' abstract 使用abstract修饰LOLHero类 * * 第三步: * 【子类报错】 * The type Thresh must implement the inherited abstract method LOLHero.q() * Thresh类必须实现继承LOLHero类内的abstract方法q * 因为abstract修饰的方法,在父类abstract类内没有方法体,子类如果想要使用abstract修饰的方法 * 必须完成方法体的实现 * 【Eclipse快速修复】 * Ctrl + 1 * 选择 Add unimplemented methods 添加未实现方法 */ abstract class LOLHero { abstract public void q(); abstract public void w(); abstract public void e(); abstract public void r(); } /** * 锤石类继承LOLHero类 * * @author Anonymous * */ class Thresh extends LOLHero { @Override public void q() { System.out.println("死亡判决"); } @Override public void w() { System.out.println("魂引之灯"); } @Override public void e() { System.out.println("厄运钟摆"); } @Override public void r() { System.out.println("幽冥监牢"); } } /** * 维鲁斯类继承LOLHero类 * * @author Anonymous * */ class Varus extends LOLHero { @Override public void q() { System.out.println("穿刺之箭"); } @Override public void w() { System.out.println("枯萎箭袋"); } @Override public void e() { System.out.println("恶灵箭雨"); } @Override public void r() { System.out.println("腐败链锁"); } } public class Demo1 { public static void main(String[] args) { Thresh saolei = new Thresh(); saolei.q(); saolei.e(); saolei.w(); saolei.r(); System.out.println("--------------------------"); Varus varus = new Varus(); varus.q(); varus.w(); varus.e(); varus.r(); } }
接口
2.接口 接口语法:interface A {} 接口内的成员变量【缺省属性】public static final 接口内的成员方法【缺省属性】public abstract 接口遵从的实现语法: class A implements B {} A类是B接口的实现类,A类遵从B接口 接口的实现类需完成接口中所有缺省值为【public abstract】的方法 一个类可以继承多个接口,接口可以继承接口 abstract修饰的类遵从接口,相对于非abstract修饰的类有什么区别?==>abstract遵从接口不强制实现任何方法 JDK1.8新特性: default关键字可以在接口中使用,用于修饰方法。使用default关键字修饰的方法在接口中允许有方法体。 【默认方法】 【非强制重写方法】 interface 接口内如果有default修饰的方法,那么这个接口的实现类可以不必强制重写default的方法 3.多态 一个方法需要的参数的是父类,那么传入父类以及父类的子类都是可以的 一个方法返回的参数的是父类,那么返回父类以及父类的子类都是可以的 一个方法需要的参数时USB接口,但是传入的对象是USB接口的实现类或者间接类也是OK的 【多态】 父类引用指向子类的对象 接口的引用指向遵从接口的类对象
类与类之间的关系:单继承
接口与接口之间关系:多实现
接口与接口之间关系:多继承
常量的定义方式: 1.类方法初始化常量,将构造方法私有化,组织用户创建对象 2.接口常量,将所有用到的常量汇总在接口中
枚举类型:
enum light{
}
内部类
成员内部类
局部内部类
package
【附加】
1. javac -d xxxx.java 带包编译(文件夹) 2. import:找到对应的class文件,引入进来就能用
3. public 修饰的类要和文件名一致
【更新履历】
1. 增加继承,内部类
2. this,super