1.类的继承:java中一个子类只能有个一父类----单继承(一个类只能继承一个父类);
java中可以多层继承,父类--->子类---->孙子类
为什么要用类的继承? 通过继承可以简化类的定义;可以扩展类的功能;
注意:子类只可以继承父类非私有的属性和方法;
class Person{
private String name;
private int age;
public void setName(String name){
this.name=name;
}
public void setAge(int age){
this.age=age;
}
public String getName(){
return this.name;
}
public int getAge(){
return this.age;
}
public String say(){
return "姓名;"+this.name+",年龄:"+this.age;
}
}
public class Demo{
public static void main(String args[]){
new Person();
}
}
//学生
class Student{
private String name;
private int age;
private String school;
public void setName(String name){
this.name=name;
}
public void setAge(int age){
this.age=age;
}
public void setSchool(String school){
this.school=school;
}
public String getName(){
return this.name;
}
public int getAge(){
return this.age;
}
public String getSchool(){
return this.school;
}
public String say(){
return "姓名;"+this.getName()+",年龄:"+this.getAge();
}
}
弊端:代码重复,好的编程应该是代码重用的,这样就有了继承---如下;
//学生
class Student extends Person{
private String school;
public void setSchool(String school){
this.school=school;
}
public String getSchool(){
return this.school;
}
public String say(){
return "姓名;"+this.getName()+",年龄:"+this.getAge()+",学校:"+this.getSchool();
}
}
2.继承的构成方法:
class A{
public A(){
System.out.println("1.A{}");
}
}
class B extends A{
public B(){
//其实此处隐藏了这样个函数:
super();//父类又叫超类,super()指的父类的构造函数;
System.out.println("2.B{}");
}
}
public class Demo{
public static void main(String args[]){
new B();
}
}
3.方法的覆写:
三种权限:
public:权限最大,任何人都可以访问;
默认(default):仅次于public
private:权限最小,只能在一个类中访问;
public>默认>private
覆写:方法名称完全一样,参数完全一样,子类方法的权限不能比
父类更严格的权限(即子类方法的权限大于等于父类方法的权限),
覆盖之后子类调用的方法永远是覆盖之后的方法;
如果父类的方法是private的那么子类是不能访问到的,所以也就不会覆写;
4.方法的重载与覆写:
重载: 方法名相同,参数的类型和个数不同;发生在同一个类中;
注:光访问权限不同其他的相同不叫方法的重载,这样编译不通过的
public class Demo{
public static void add(){
System.out.println("1.add……");
}
static void add(){
System.out.println("1.add……");
}
public static void main(String args[]){
}
}
覆写:方法名相同,访问权限子类大于等于父类;参数的类型和个数一样;发生在继承关系中;
5.super关键字:在子类对象实例化时,在子类的构造方法中,默认隐含了一个super()的代码,
调用父类[超类]中的构造方法;
a.super可以调用父类中被覆盖的方法:super.方法();
b.super可以调用父类中的属性:super.属性名;
6.supper 和 this的区别:
this指的是本来;调用本类的非私有的属性和方法;在构造函数的首行、并且至少有一个构造方法没有用this调用;
supper指的是父类;调用父类的非私有的属性和方法;在子类构造方法的第一行,默认情况下隐藏;
7.final 关键字:
1.被final标识的类,不能有子类,即不能被继承;
2.被final标识的方法,不能被覆写;(一下是个错误的例子)
3.被final修饰的变量不能被修改,即变成常量;
class A{
public final void fun(){
}
}
class B extends A{
public void fun(){
}
}
3.被final标记的变量是常量,被final标记的变量,最好用大写;
4.被 public static final 标记的称谓 “全局静态常量”;(常量是 不能被修改的)
8.抽象类:
1.所谓的抽象类,就是包含一个抽象方法的类;
抽象方法:只有声明没有实现的方法--(没有方法体的方法);
abstract class A{
public void fun2(){
System.out.println("test");
}
public abstract void fun();----用abstract标识、切没有方法体;
}
2.抽象类与普通类的差别:
比普通类的定义中多处一个抽象方法,普通类的所有定义在抽象类中都可以使用;
在类的声明出需要用到abstract声明为抽象类,抽象方法也必须用abstract声明;
3.抽象类不能被实例化;
抽象类的子类(如果子类不是抽象类)必须实现父类的所有抽象方法;
抽象类必须有子类,要不就没有用了;
4.抽象类本身可以有构造方法:
与普通的继承一样,抽象方法的子类(非抽象方法)在实例化时也是先实例化父类的属性,
在实例化子类中的属性;
5.继承中的构造方法:
子类的构造方法方法中有个默认的super()方法,即父类的构造方法;
当父类定义了带参数的构造方法,而没有定义无参数构造函数,这是无参数的
构造函数就不存在了,此时子类是不能用父类的无参数构造函数了;
6.抽象类一定不可以被 final 标识的:
抽象类被子类继承才有意义的,所以抽象类是不能被final修饰的;
9.接口:接口是抽象方法和常量的结合;
1.接口包含:全局静态常量和抽象方法;
interface A{
public static final String INFO="lid";
public abstract void fun();
}
由于 接口的定义就是只包含全局静态常量和抽象方法所以一般都简写成如下样式:
interface A{
String INFO="lid";//系统会默认为其加上public static final
public void fun();// 系统默认会为其加上 abstract
}
2.接口的访问权限永远是public;
3.子类可以同时实现多个接口和继承抽象类---(先继承抽象类,在实现接口)
interface A{
String AINFO="lid";
public void aSay();
}
interface B{
String BINFO="yuj";
public void bSay();
}
abstract class C{
public abstract void cSay();
}
class X extends C implements A,B{
public void aSay(){
System.out.println("A接口中的方法……");
}
public void bSay(){
System.out.println("B接口中的方法……");
}
public void cSay(){
System.out.println("C抽象类中的方法……");
}
}
public class Demo{
public static void main(String args[]){
X x=new X();
x.aSay();
x.bSay();
x.cSay();
}
}
4.接口可以extends多个接口---(类只能继承一个父类,接口则可以继承多个 接口)
interface A{
public void printA();
}
interface B{
public void printB();
}
interface C extends A,B{
public void printC();
}
//因为D是抽象类,可以不用实现父类或者说接口的抽象方法,
//如果D不是抽象类,而是普通类,则必须实现所有的抽象方法;
abstract class D implements C{
public abstract void printD();
}
class X extends D{
public void printA(){
System.out.println("Hello A……");
}
public void printB(){
System.out.println("Hello B……");
}
public void printC(){
System.out.println("Hello C……");
}
public void printD(){
System.out.println("Hello D……");
}
}
public class Demo{
public static void main(String args[]){
X x=new X();
x.printA();
x.printB();
x.printC();
x.printD();
}
}
10.多态:---其实多态主要是为了接口的,接口只管定义方法,子类实现接口的方法实现不同的功能;
向继承:父类不能访问到子类的 新添加的方法和属性的,所以多态尽量用在接口上和实现接口的类上;
方法的多态性(方法的重载):同一个方法名根据传入的参数不同,完成的功能不同;
对象的多态性:子类对象与父类对象之间的转换---即在继承上一种扩展;
面向对象程序开发的一个思路:【建议】永远不去继承一个普通的类---当然看情况而变;
对象多态性是在继承应用上的一种扩展,所以程序要现有继承关系才能够去使用多态性;
1.向上转型:子类-->父类,自动转型;
注意:转型之后,父类是看不到子类新增的方法的;
转型了,但是用处呢?
如果一个方法被子类覆写了,则子类与父类之间发生转换时,自动去调用
已经不覆写过的方法,即子类的方法;
2.向下转型:父类-->子类,强制转型;
class A{
public void fun1(){
System.out.println("1、A--->public void fun1()");
}
public void fun2(){
this.fun1();
}
}
class B extends A{
//覆写了A中的fun1
public void fun1(){
System.out.println("2、B--->public void fun1()");
}
//增加了一个fun3()方法
public void fun3(){
System.out.println("3、B--->public void fun3()");
}
}
public class Demo{
public static void main(String args[]){
A a=null;
a=new B();
//子类对象为父类实例化;
a.fun2();
a.fun3();//是看不到的;
//向下转型必须强制转型
B b=null;
b=(B)a;
a.fun2();
}
}
注意:如果向下转型必须先向上转型在向下转型,即:
A a=new B();//向上转型;
B b=(B)a;//向下转型;
(这个时候的a可以看到B中继承A的所有内容,但是不能看到B新增的内容;
而此时的b可以看到B中的所有内容;)
如果直接这样写:
A a=new A();
B b=(B) a;
这样直接写是会报错的,可以从 栈内存和堆内存上分析;
3.对象多态的意义:和方法多态一样(通过调用一个方法传入不同的参数去实现不同功能),
对象的多态也是通过传入不同的对象实现不同的功能;
class A{
}
class B extends A{
}
class C extends B{
}
public class Demo{
public static void main(String args[]){
printer(new A());
printer(new B());
printer(new C());
}
public static void printer(A a){
……
if(a instanceof B){
……
}
if(a instanceof C){
……
}
}
}
4.instanceof 是关键字,不是一个方法;a instanceof A 意思是:a是A的实例;