Java不支持多重继承,是单继承,一个类只能有一个父类。
1、作用域
作用域 | 当前类 | 同一package | 子孙类 | 其他package |
public | √ | √ | √ | √ |
protected | √ | √ | √ | × |
default(同包) | √ | √ | × | × |
private | √ | × | × | × |
2、intanceof运算符
其左面的操作元是对象,右面的操作元是类,当左面的操作元是右面的类或者子类的时候,运算结果为true,否则为false。例如:
Student student = new Student();
student instanceof Student的运算结果为true;
3、成员变量的隐藏
当子类中成员变量的名字与父类的相同的时候(声明类型可以不同),子类就会隐藏所继承的成员变量。即:
(1)子类对象及子类自己定义的方法操作与父类同名的成员变量是指子类重新声明的成员变量。
(2)子类仍然可以调用从父类继承的方法操作被子类隐藏的成员变量,也就是说,子类继承的方法所操作的成员变量一定是被子类继承或隐藏的成员变量。
详细理解参考以下代码
public class Main {
public double weigh;
public void oldSetWeight(double w){
weigh = w;
System.out.println("double类型的weight"+weigh);
}
public double oleGetPrice(){
double price = weigh*10;
return price;
}
}
public class New extends Main {
private int weight;
public void newSetWeight(double w){
weigh = w;
System.out.println("int类型的weight"+weigh);
}
public double newGetPrice(){
double price = weigh*10;
return price;
}
}
public class Test {
public static void main(String args[]){
New goods = new New();
goods.newSetWeight(198);
System.out.println(goods.weigh);
System.out.println(goods.newGetPrice());
goods.oldSetWeight(198.7);
System.out.println(goods.oleGetPrice());
}
}
运行结果为:
int类型的weight198.0
198.0
1980.0
double类型的weight198.7
1987.0
4、方法重写(方法覆盖)
子类的返回值类型、方法名、参数类型及个数都要与父类继承的方法相同。
如果子类重写了父类的方法f(),就会隐藏父类的f(),子类对象调用的方法f()一定是重写的方法f()。
重写方法不能调用被子类隐藏的成员变量和方法。(使用super关键字可以)
重写方法时不允许降低方法的访问权限(访问权限从高到低的排列顺序是public、proteced、friendly、private)
区分重载和重写
override(重写)
1、方法名、参数、返回值相同。
2、子类方法不能缩小父类方法的访问权限。
3、子类方法不能抛出比父类方法更多的异常(但子类方法可以不抛出异常)。
4、存在于父类和子类之间。
5、方法被定义为final不能被重写。
overload(重载)
1、参数类型、个数、顺序至少有一个不相同。
2、不能重载只有返回值不同的方法名。
3、存在于父类和子类、同类中。
5、super关键字
使用super可以访问被子类隐藏的成员变量和方法。
当super调用被隐藏的方法时,该方法中出现的成员变量是被子类隐藏的成员变量或者继承的成员变量。
super不能用于static方法中。
子类的构造方法会先调用父类的某个构造方法,可以使用super来调用父类的某个构造方法(必须置于构造方法的首行),如果子类没有明确指出调用父类的哪个构造方法,那么默认的有:
super();即调用父类的默认构造函数。
以上的内容可以参考以下代码理解:
public class A {
int n;
int a;
int b;
A(){
}
A(int a, int b){
this.a = a;
this.b = b;
System.out.println(a);
System.out.println(b);
}
float computer(float x,float y){
return x+y;
}
public int g(int x,int y){
return x+y;
}
float f(){
float sum = 0;
for (int i = 1; i <= n; i++){
sum =sum + i;
}
return sum;
}
}
public class B extends A{
int n;
boolean c;
B(){}
B(int a,int b,boolean c){
super(a,b);
c = true;
System.out.println(c);
}
float computer(float x,float y){
return x*y;
}
float f(){
float c;
super.n = n;
c = super.f();
System.out.println(c);
return c/n;
}
float g(){
float c;
c = super.f();
return c/2;
}
}
public class C {
public static void main(String args[]){
B b3 = new B(1,2,false);
B b = new B();
double result = b.computer(8,9);
System.out.println(result);
int m = b.g(12,8);
System.out.println(m);
B b2 = new B();
b.n = 100;
System.out.println(b.g());
System.out.println(b.f());
}
}
运行结果:
E:\JavaIDE\jdk-9.0.4_windows-x64_bin\bin\java "-javaagent:E:\JavaIDE\Javaanzhuang\IntelliJ IDEA Community Edition 2017.3.3\lib\idea_rt.jar=63206:E:\JavaIDE\Javaanzhuang\IntelliJ IDEA Community Edition 2017.3.3\bin" -Dfile.encoding=UTF-8 -classpath E:\untitled\out\production\untitled ExtendTest.C
1
2
true
72.0
20
0.0
5050.0
50.5
Process finished with exit code 0
6、子类实例化过程
<1>类加载
1、父类的static属性
2、父类的static块
3、子类的static属性
4、子类的static块
<2>实例化
5、父类的普通属性
6、父类的构造块
7、父类的构造函数
8、子类的普通属性
9、子类的构造块
10、子类的构造函数
根据以下代码的输出结果做测试:
public class ClzInit {
public static void main(String[] args) {
new Son();
}
}
class Parent {
protected int n = 5;
protected static int m = 5;
static {
m = m * 2;
System.out.println("父类静态块调用m="+m);
}
{
n = n * 2;
m = m * 2;
System.out.print("父类构造块");
System.out.print("n="+n);
System.out.println("m="+m);
}
public Parent() {
this.n = n * 10;
m = m + 10;
System.out.print("父类构造函数n="+n);
System.out.println("m="+m);
}
public Parent(int n) {
this.n = n * 10;
System.out.println("这是带参数的父类构造方法");
}
}
class Son extends Parent {
private int sn=3;
private static int sm=3;
static {
m = m + 2;
sm=sm+2;
System.out.println("子类静态块调用m="+m);
}
{
n = n + 2;
sn=sn+2;
m = m + 2;
System.out.println("子类构造块调用");
System.out.print("n="+n);
System.out.print(" sn="+sn);
System.out.println(" m="+m);
}
public Son() {
//super();
//super(10);
this.n = n + 10;
sn=sn+10;
m = m + 10;
System.out.print("子类构造函数n="+n);
System.out.println("m="+m);
}
}
正确答案是:
父类静态块调用m=10
子类静态块调用m=12
父类构造块n=10m=24
父类构造函数n=100m=34
子类构造块调用
n=102 sn=5 m=36
子类构造函数n=112m=46
7、final关键字
·修饰变量(只能初始化一次)
·修饰方法(该方法不能被重写,老老实实继承,但是可以被重载)
·修饰类(该类不能被继承)
8、对象的上转型对象
(1)上转型对象不能调用子类新增的成员变量和方法。
(2)上转型对象可以访问子类继承和隐藏的成员变量、子类继承的方法或者子类重写的方法。
(3)上转型对象不能调用子类重写的静态方法,只能调用父类的静态方法。
参考以下代码进行理解:
public class Animal {
void speak(String s){
System.out.println(s);
}
}
public class Dog extends Animal {
void computer(int a,int b){
int c = a*b;
System.out.println(c);
}
void speak(String s){
System.out.println("***"+s+"***");
}
}
public class Test {
public static void main(String args[]){
Animal animal;
Dog dog = new Dog();
animal = dog;
animal.speak("I Love You"); //animal是dog的上转型对象
Dog dog1 = (Dog)animal; //把上转型对象强制转为子类对象
dog1.computer(10,10);
}
}
运行结果为:
E:\JavaIDE\jdk-9.0.4_windows-x64_bin\bin\java "-javaagent:E:\JavaIDE\Javaanzhuang\IntelliJ IDEA Community Edition 2017.3.3\lib\idea_rt.jar=63559:E:\JavaIDE\Javaanzhuang\IntelliJ IDEA Community Edition 2017.3.3\bin" -Dfile.encoding=UTF-8 -classpath E:\untitled\out\production\untitled people.Test
***I Love You***
100
Process finished with exit code 0
9、abstract类和abstract方法
抽象类中必须要有抽象方法,在子类中必须重写抽象方法。
抽象类可以包含属性、方法、构造函数,但是不能被实例化,即不能用new来实现实例化抽象类。
抽象类只能被继承。
public class AmericanGirlFriend extends GirlFriend {
@Override
void speak() {
System.out.println("hello");
}
@Override
void cooking() {
System.out.println("beef");
}
}
public class Boy {
GirlFriend girlFriend;
void setGirlFriend(GirlFriend f){
girlFriend = f;
}
void showGrilFriend(){
girlFriend.speak();
girlFriend.cooking();
}
}
public class ChinaGirldFriend extends GirlFriend {
@Override
void speak() {
System.out.println("你好");
}
@Override
void cooking() {
System.out.println("水煮鱼");
}
}
public abstract class GirlFriend {
abstract void speak();
abstract void cooking();
}
public class Test {
public static void main(String args[]){
GirlFriend friend = new ChinaGirldFriend(); //向上转型
Boy boy = new Boy();
boy.setGirlFriend(friend);
boy.showGrilFriend();
friend = new AmericanGirlFriend();
boy.setGirlFriend(friend);
boy.showGrilFriend();
}
}
运行结果如下:
E:\JavaIDE\jdk-9.0.4_windows-x64_bin\bin\java "-javaagent:E:\JavaIDE\Javaanzhuang\IntelliJ IDEA Community Edition 2017.3.3\lib\idea_rt.jar=63880:E:\JavaIDE\Javaanzhuang\IntelliJ IDEA Community Edition 2017.3.3\bin" -Dfile.encoding=UTF-8 -classpath E:\untitled\out\production\untitled AbstractTest.Test
你好
水煮鱼
hello
beef
Process finished with exit code 0