**
this和super的使用方法:
**
注:只要子类构造方法被调用,都会先访问父类的无参构造方法
继承整理:
package com.company;
//===============================继承extends===========================================
/*
继承:
代码中相同的部分提取出来组成 一个父类;其他类需要时继承过来;
不支持一个子类有多个父类,但是一个父类可以后多个子类;
子类拥有父类非 private 的属性、方法。
子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。
子类可以用自己的方式实现父类的方法。
Java 的继承是单继承,但是可以多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,例如 B 类继承 A 类,C 类继承 B 类,所以按照关系就是 B 类是 C 类的父类,A 类是 B 类的父类,这是 Java 继承区别于 C++ 继承的一个特性。
提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系越紧密,代码独立性越差)。
父类:
public class Animal { //父类
private String name;
private int id;
public Animal(String myName, int myid) {
name = myName;
id = myid;
}
public void eat(){
System.out.println(name+"正在吃");
}
public void sleep(){
System.out.println(name+"正在睡");
}
public void introduction() {
System.out.println("大家好!我是" + id + "号" + name + ".");
}
}
子类1:
public class Penguin extends Animal { //Penguin类 extends继承 Animal
public Penguin(String myName, int myid) { //构造方法
super(myName, myid); //继承父类
}
}
子类2:
public class Mouse extends Animal { //Mouse类 extends继承 Animal
public Mouse(String myName, int myid) { //构造方法
super(myName, myid); //继承父类
}
}
继承关键字:
所有的类都是继承于 java.lang.Object,当一个类没有继承,则默认继承object(这个类在 java.lang 包中,所以不需要 import)祖先类
extends关键字:
单一继承,一个子类只能拥有一个父类,extends 只能继承一个类
public class Penguin extends Animal{
}
implements关键字:
implements 关键字可以变相的使java具有多继承的特性,使用范围为类继承接口;
可以同时继承多个接口(接口跟接口之间采用逗号分隔)
public interface A { //接口A
public void eat();
public void sleep();
}
public interface B { //接口B
public void show();
}
public class C implements A,B { //接口C,继承接口 A,B
}
super 与 this 关键字:
super关键字:实现对父类成员的访问,用来引用当前对象的父类
this关键字:指向自己的引用
例子:
class Animal { //父类
void eat() {
System.out.println("animal : eat");
}
}
class Dog extends Animal { //子类Dog
void eat() {
System.out.println("dog : eat");
}
void eatTest() {
this.eat(); // this 调用自己的成员方法
super.eat(); // super 调用父类成员方法
}
}
public class Test {
public static void main(String[] args) {
Animal a = new Animal();
a.eat();
Dog d = new Dog();
d.eatTest();
}
}
输出:animal : eat dog : eat animal : eat
final关键字:
final 关键字声明类可以把类定义为不能继承的,即最终类;或者用于修饰方法,该方法不能被子类重写:
final class 类名 {//类体}
修饰符(public/private/default/protected) final 返回值类型 方法名(){//方法体}
注:实例变量也可以被定义为 final,被定义为 final 的变量不能被修改;
被声明为 final 类的方法,自动地声明为 final,但是实例变量并不是 final;
构造器:
子类是不继承父类的构造器(构造方法或者构造函数)的,它只是调用(隐式或显式)
父类的构造器带有参数,子类的构造器中必须显式地通过 super 关键字调用父类的构造器并配以适当的参数列表
父类构造器没有参数,子类的构造器中不需要使用 super 关键字调用父类构造器,系统会自动调用父类的无参构造器
class SuperClass {
private int n;
SuperClass(){
System.out.println("SuperClass()");
}
SuperClass(int n) {
System.out.println("SuperClass(int n)");
this.n = n;
}
}
// SubClass 类继承
class SubClass extends SuperClass{
private int n;
SubClass(){ // 自动调用父类的无参数构造器
System.out.println("SubClass");
}
public SubClass(int n){
super(300); // 调用父类中带有参数的构造器
System.out.println("SubClass(int n):"+n);
this.n = n;
}
}
// SubClass2 类继承
class SubClass2 extends SuperClass{
private int n;
SubClass2(){
super(300); // 调用父类中带有参数的构造器
System.out.println("SubClass2");
}
public SubClass2(int n){ // 自动调用父类的无参数构造器
System.out.println("SubClass2(int n):"+n);
this.n = n;
}
}
public class TestSuperSub{
public static void main (String args[]){
System.out.println("------SubClass 类继承------");
SubClass sc1 = new SubClass();
SubClass sc2 = new SubClass(100);
System.out.println("------SubClass2 类继承------");
SubClass2 sc3 = new SubClass2();
SubClass2 sc4 = new SubClass2(200);
}
}
输出结果:
------SubClass 类继承------
SuperClass()
SubClass
SuperClass(int n)
SubClass(int n):100
------SubClass2 类继承------
SuperClass(int n)
SubClass2
SuperClass()
SubClass2(int n):200
*/
public class Extendsa {
}
重写:
重写的整理:
package com.company;
//===============================Java 重写(Override)与重载(Overload)===========================================
/*
重写(Override):
子类对父类允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变;
子类可以根据需要,定义特定于自己的行为
不能抛出新的检查异常或者比被重写方法申明更加宽泛的异常;例如: 父类的一个方法申明了一个检查异常 IOException,但是在重写这个方法的时候不能抛出 Exception 异常,因为 Exception 是 IOException 的父类,抛出 IOException 异常或者 IOException 的子类异常
例子:
class Animal{
public void move(){
System.out.println("动物可以移动");
}
}
class Dog extends Animal{
public void move(){
System.out.println("狗可以跑和走");
}
}
方法重写规则:
访问权限不能比父类中被重写的方法的访问权限更低;父类的一个方法被声明为 public,那么在子类中重写该方法就不能声明为 protected
参数列表与被重写方法的参数列表必须完全相同
返回类型与被重写方法的返回类型可以不相同,但是必须是父类返回值的派生类
父类的成员方法只能被它的子类重写
声明为 final 的方法不能被重写
声明为 static 的方法不能被重写,但是能够被再次声明
子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为 private 和 final 的方法
子类和父类不在同一个包中,那么子类只能够重写父类的声明为 public 和 protected 的非 final 方法
重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以
构造方法不能被重写
如果不能继承一个类,则不能重写该类的方法
Super关键字:
需要在子类中调用父类的被重写方法时使用
class Animal{
public void move(){
System.out.println("动物可以移动");
}
}
class Dog extends Animal{
public void move(){
super.move(); // 应用super类的方法
System.out.println("狗可以跑和走");
}
}
重载(Overload):
在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同
每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表
最常用的地方就是构造器的重载
public class Overloading {
public int test(){
System.out.println("test1");
return 1;
}
public void test(int a){
System.out.println("test2");
}
//以下两个参数类型顺序不同
public String test(int a,String s){
System.out.println("test3");
return "returntest3";
}
public String test(String s,int a){
System.out.println("test4");
return "returntest4";
}
public static void main(String[] args){
Overloading o = new Overloading();
System.out.println(o.test());
o.test(1);
System.out.println(o.test(1,"test3"));
System.out.println(o.test("test4",1));
}
}
重载规则:
被重载的方法必须改变参数列表(参数个数或类型不一样);
被重载的方法可以改变返回类型;
被重载的方法可以改变访问修饰符;
被重载的方法可以声明新的或更广的检查异常;
方法能够在同一个类中或者在一个子类中被重载。
无法以返回值类型作为重载函数的区分标准。
重写与重载之间的区别:
区别点 重载方法 重写方法
参数列表 必须修改 一定不能修改
返回类型 可以修改 一定不能修改
异常 可以修改 可以减少或删除,一定不能抛出新的或者更广的异常
访问 可以修改 一定不能做更严格的限制(可以降低限制)
java多态性的不同表现:
重写和重载
方法的重载:
一个类中定义了多个方法名相同,而他们的参数的数量不同或数量相同而类型和次序不同
子类与父类的一种多态性表现
方法重写:
子类存在方法与父类的方法的名字相同,而且参数的个数与类型一样
一个类的多态性表现
*/
public class Overridea {
}
**
包:
**
**
权限修饰符:
**
权限修饰符的整理:
package com.company;
//===============================访问控制修饰符===========================================
/*
访问控制修饰符:
public:对所有类可见。使用对象:类、接口、变量、方法
private : 在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部类)
default (即默认,什么也不写): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。
protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)。
访问控制和继承:
父类中声明为 public 的方法在子类中也必须为 public。
父类中声明为 protected 的方法在子类中要么声明为 protected,要么声明为 public,不能声明为 private。
父类中声明为 private 的方法,不能够被子类继承。
非访问修饰符:
static 修饰符:静态变量
*/
public class Modifier {
//默认访问修饰符 default(不使用任何修饰符,默认default)
String a1 = "1.2"; //定义一个默认类型的字符串
boolean possOrder(){ //定义一个默认类型的方法
return true;
}
//私有访问修饰符 private
private String format;
public String getFormat() {
return this.format;
}
public void setFormat(String format) { //Logger 类中的 format 变量为私有变量,所以其他类不能直接得到和设置该变量的值。为了使其他类能够操作该变量,定义了两个 public 方法:getFormat() (返回 format的值)和 setFormat(String)(设置 format 的值)
this.format = format;
}
//公有访问修饰符 public
public static void main(String[] arguments) { //Java 程序的 main() 方法必须设置成公有的,否则,Java 解释器将不能运行该类。
}
//受保护的访问修饰符 protected
//子类与基类在同一包中:被声明为 protected 的变量、方法和构造器能被同一个包中的任何其他类访问;
//子类与基类不在同一包中:那么在子类中,子类实例可以访问其从基类继承而来的 protected 方法,而不能访问基类实例的protected方法。
}
final修饰符:
**
static:
**
**
多态:
**
多态的整理:
package com.company;
//===============================多态===========================================
/*
多态:
同一个接口,使用不同的实例而执行不同的操作
多态存在的三个必要条件:
继承
重写
父类引用指向子类对象:Parent p = new Child();
例子:
class Shape {
void draw() {}
}
class Circle extends Shape {
void draw() {
System.out.println("Circle.draw()");
}
}
使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法
多态实例:
public class Test {
public static void main(String[] args) {
show(new Cat()); // 以 Cat 对象调用 show 方法
show(new Dog()); // 以 Dog 对象调用 show 方法
Animal a = new Cat(); // 向上转型
a.eat(); // 调用的是 Cat 的 eat ;编译看左边,执行看右边
a.age; // 2 调用的是 Animal 的 age ;编译看左边,执行看左边
Cat c = (Cat)a; // 向下转型
c.work(); // 调用的是 Cat 的 work
}
public static void show(Animal a) {
a.eat();
// 类型判断
if (a instanceof Cat) { // 猫做的事情
Cat c = (Cat)a;
c.work();
} else if (a instanceof Dog) { // 狗做的事情
Dog c = (Dog)a;
c.work();
}
}
}
abstract class Animal {
Int age = 2;
abstract void eat();
}
class Cat extends Animal {
Int age = 1;
public void eat() {
System.out.println("吃鱼");
}
public void work() {
System.out.println("抓老鼠");
}
}
class Dog extends Animal {
public void eat() {
System.out.println("吃骨头");
}
public void work() {
System.out.println("看家");
}
}
虚函数:
虚函数的存在是为了多态
动态绑定是Java的默认行为
不希望某个函数具有虚函数特性,可以加上 final 关键字变成非虚函数
重写:
当子类对象调用重写的方法时,调用的是子类的方法,而不是父类中被重写的方法
要想调用父类中被重写的方法,则必须使用关键字 super
虚拟方法:
多态的实现方式:
重写,重载
接口
抽象类和抽象方法
*/
public class Manya {
}
抽象类:
package com.company;
//===============================抽象类===========================================
/*
抽象类:
不能实例化对象,其他功能和一般的类一样
因为不能实例化对象,所以抽象类必须被继承,才能被使用
抽象类表示的是一种继承关系,一个类只能继承一个抽象类,而一个类却可以实现多个接口
定义抽象类 abstract class:
public abstract class Employee //定义一个抽象类Employee,不能被实例化,只能被继承
{
private String name;
public Employee(String name, String address, int number)
{
System.out.println("Constructing an Employee");
}
}
抽象方法:
抽象方法具体实现由它的子类确定
抽象方法只包含一个方法名
抽象方法没有定义,方法名后面直接跟一个分号,而不是花括号
一个类包含抽象方法,那么该类必须是抽象类
任何子类必须重写父类的抽象方法,或者声明自身为抽象类
必须有子类实现该抽象方法,否则,从最初的父类到最终的子类都不能用来实例化对象
定义抽象方法 abstract:
public abstract class Employee
{
private String name;
public abstract double computePay(); //抽象方法computePay
}
子类重写抽象类的方法:
public class Salary extends Employee
{
private double salary;
public double computePay() //子类实现父类的抽象方法computePay()
{
System.out.println("Computing salary pay for " + getName());
return salary/52;
}
}
注意:
抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类
抽象类中的抽象方法只是声明,不包含方法体,就是不给出方法的具体实现也就是方法的具体功能
构造方法,类方法(用 static 修饰的方法)不能声明为抽象方法
抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象类
*/
public class Abstracta {
}
接口:
package com.company;
//===============================接口Interface===========================================
/*
接口:
是一个抽象类型,是抽象方法的集合,接口通常以interface来声明;
一个类通过继承接口的方式,从而来继承接口的抽象方法;
接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念
除非实现接口的类是抽象类,否则该类要定义接口中的所有方法
接口无法被实例化,但是可以被实现
接口与类区别:
接口不能用于实例化对象。
接口没有构造方法。
接口中所有的方法必须是抽象方法,Java 8 之后 接口中可以使用 default 关键字修饰的非抽象方法
接口不能包含成员变量,除了 static 和 final 变量
接口不是被类继承了,而是要被类实现。
接口支持多继承。
接口特性:
接口中每一个方法也是隐式抽象的,接口中的方法会被隐式的指定为 public abstract(只能是 public abstract,其他修饰符都会报错)。
接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量(并且只能是 public,用 private 修饰会报编译错误)。
接口中的方法是不能在接口中实现的,只能由实现接口的类来实现接口中的方法。
抽象类和接口的区别
1. 抽象类中的方法可以有方法体,就是能实现方法的具体功能,但是接口中的方法不行。
2. 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是 public static final 类型的。
3. 接口中不能含有静态代码块以及静态方法(用 static 修饰的方法),而抽象类是可以有静态代码块和静态方法。
4. 一个类只能继承一个抽象类,而一个类却可以实现多个接口。
注:JDK 1.8 以后,接口里可以有静态方法和方法体了。
注:JDK 1.8 以后,接口允许包含具体实现的方法,该方法称为"默认方法",默认方法使用 default 关键字修饰。更多内容可参考 Java 8 默认方法。
接口声明 interface:
[可见度(public等)] interface 接口名称 [extends 其他的接口名] {
// 声明变量
// 抽象方法
}
接口有以下特性:
接口是隐式抽象的,当声明一个接口的时候,不必使用abstract关键字。
接口中每一个方法也是隐式抽象的,声明时同样不需要abstract关键字。
接口中的方法都是公有的。
接口实现 implements:
public class MammalInt implements Animal{ //MammalInt类实现接口Animal
public void eat(){
System.out.println("Mammal eats");
}
public void travel(){
System.out.println("Mammal travels");
}
public int noOfLegs(){
return 0;
}
public static void main(String args[]){
MammalInt m = new MammalInt();
m.eat();
m.travel();
}
}
类在实现接口的方法时,不能抛出强制性异常,只能在接口中,或者继承接口的抽象类中抛出该强制性异常。
类在重写方法时要保持一致的方法名,并且应该保持相同或者相兼容的返回值类型。
如果实现接口的类是抽象类,那么就没必要实现该接口的方法。
一个类只能继承一个类,但是能实现多个接口。
接口继承 extends:
// 文件名: Sports.java
public interface Sports
{
public void setHomeTeam(String name);
public void setVisitingTeam(String name);
}
// 文件名: Football.java
public interface Football extends Sports
{
public void homeTeamScored(int points);
public void visitingTeamScored(int points);
public void endOfQuarter(int quarter);
}
// 文件名: Hockey.java
public interface Hockey extends Sports
{
public void homeGoalScored();
public void visitingGoalScored();
public void endOfPeriod(int period);
public void overtimePeriod(int ot);
}
Hockey接口自己声明了四个方法,从Sports接口继承了两个方法,这样,实现Hockey接口的类需要实现六个方法。
相似的,实现Football接口的类需要实现五个方法,其中两个来自于Sports接口
接口的多继承:
只需要使用一次extends关键字:
public interface Hockey extends Sports, Event
标记接口:
没有任何方法的接口
public interface EventListener
{}
*/
public class Interfacea {
}
内部类: