继承:把类中公共的部分抽取出来,做成一个公共的类,让其他类和我们公共的类产生关系,让我们自己的类可以使用公共类。
这个关系就是继承。
java中也可以有继承,java中的继承指的就是类与类的继承。
格式:使用extends关键字。
class 子类 extends 父类{
}
被继承的那个类:我们称之为父类、基类、超类
继承的那个类:我们称之为子类、派生类。
继承的作用:
相当于把父类中的内容,拿到了子类中。继承之后,父类中的成员,子类都可以访问(除了private)。
继承的优点:
1.提高了代码的复用性
2.提高了代码的可维护性。
3.为多态提供了前提。
class Person {
//名字
String name;
//年龄
int age;
}
//自定义一个学生类
class Student extends Person {
public void study(){
System.out.println("上课学习");
}
}
//自定义一个教师类
class Teacher {
public void teach(){
System.out.println("讲课");
}
}
class ExtendsDemo {
public static void main(String[] args) {
Student s = new Student();
System.out.println(s.name);
}
}
继承的特点:
1.继承只能单继承。(一个人只能有一个亲生父亲,一个类只能有一个父类)
2.继承可以多重(多层)继承。(一个人只能有一个亲生父亲,但是还可以有亲爷爷)
class Ye {
int age;
}
class Fu extends Ye {
String name;
}
class Zi extends Fu {
}
class ExtendsDemo2 {
public static void main(String[] args) {
Zi z = new Zi();
System.out.println(z.name);
System.out.println(z.age);
}
}
继承的注意事项:
1.继承必须是 “is a” 的关系
2.私有的成员,因为权限问题,不能使用。
3.java不支持部分继承。也就是说,如果继承就是全部继承。如果不继承就全部都不继承。
class Animal {
String name;
int age;
}
class Cat extends Animal {
}
class Dog extends Animal {
}
class ExtendsDemo3 {
public static void main(String[] args) {
Cat c = new Cat();
System.out.println(c.age);
}
}
类在使用变量时:使用就近原则。
继承间成员变量的使用规则:也是就近原则。
a.先找方法内的局部变量
b.再找本类的成员变量。
c.再找父类的成员变量。
d.如果还找不到,则报错。//找不到符号
当局部变量、本类成员变量、父类成员变量都重名时:
使用局部变量:直接使用名字。//因为就近原则,就直接找到了。
使用本类成员变量:this.成员变量
使用父类成员变量:super.成员变量
继承间成员变量的注意事项:
1.访问父类的父类的成员变量,不能使用super.super
class Ye {
int age = 80;
}
class Fu extends Ye {
int age = 20;
public int getYeAge(){
return super.age;
}
int yeAge = super.age;
}
class Zi extends Fu{
int age = 18;
public void method(){
int age = 16;
System.out.println(age); //使用局部变量
System.out.println(this.age); //使用本类成员变量
System.out.println(super.age); //使用父类成员变量
//System.out.println(super.(super.age));
}
}
class ExtendsDemo4 {
public static void main(String[] args) {
Zi z= new Zi();
z.method();
}
}
super关键字:对比this关键字
this可调用:
成员变量:this.成员变量
成员方法:this.成员方法
构造方法:this(参数) //调用本类的其他构造方法
super可以调用:
成员变量:super.成员变量 //当本类和父类的成员变量重名时,使用“super.成员变量”访问父类的成员变量
成员方法:super.成员方法 //调用父类的成员方法。
构造方法:super(参数) //父类的构造函数
继承中变量的使用原则:就近原则
继承中方法的使用原则:就近原则。
class Fu {
int age = 20;
public void method(){
System.out.println("父类的method方法");
}
}
class Zi extends Fu {
int age = 18;
public void test(){
//System.out.println(this.age);
//System.out.println(super.age);
super.method();
}
public void method(){
System.out.println("子类的method方法");
}
}
class SuperDemo {
public static void main(String[] args) {
Zi z = new Zi();
z.test();
}
}
super在使用构造方法时:
1.当我们子类构造方法中不写“super(参数)”,系统会默认添加一个“super()”
2.super(参数)必须是构造方法的第一行。this(参数)和super(参数)不能同时出现。
3.避免构造方法之间相互循环调用。
4.子类之间构造方法不管第一句是this还是super,最终必定有一个构造方法去调用super(参数)
class Fu {
public Fu(){
System.out.println("父类的无参");
}
public Fu(String s){
System.out.println("父类的有参");
}
}
class Zi extends Fu {
public Zi(){
this("");
System.out.println("子类的无参构造方法");
}
public Zi(String s){
this();
System.out.println("子类的有参构造方法");
}
}
class SuperDemo2 {
public static void main(String[] args) {
Zi z1 = new Zi();
System.out.println("-----------------------");
Zi z2 = new Zi("有参");
}
}
也就是说,如果我们使用静态成员,不管是使用谁的对象来调用,都相当于 类名.成员
class Fu {
static String name = "张三丰";
}
class Zi extends Fu {
public Zi(){
super();
name = "张翠山";
}
}
class SuperDemo4 {
public static void main(String[] args) {
Zi z = new Zi();
z.name = "谢逊"; //z.name 其实相当于 Fu.name
Fu f = new Fu();
//f.name; 相当于 Fu.name
System.out.println(f.name);
}
}
方法重写:方法覆盖、方法覆写。子类方法把父类方法(隐藏)了。
格式要去:
方法重写要求:除了访问修饰符、和方法体,其他都必须一样。
方法重写的意义:
当我们对父类的方法不满意的时候,我们可以使用方法重写,把父类的方法给隐藏掉。
class Fu {
public void method(){
System.out.println("给12345这个账户打1W¥");
}
}
class Zi extends Fu{
public void method(){
System.out.println("没钱了,先欠着");
}
public void test(){
method();
}
}
class OverrideDemo {
public static void main(String[] args) {
Zi z = new Zi();
z.method();
}
}
class Animal {
public void eat(){
System.out.println("素食");
}
}
class Dog extends Animal{
public void eat(){
System.out.println("骨头");
}
}
class OverrideDemo2 {
public static void main(String[] args) {
Dog d = new Dog();
d.eat();
}
}
方法重写的作用:
1.把父类的方法拿过来,修改掉
2.扩展父类的功能.
方法重载和方法重写的区别:
方法重载:
方法名相同、参数列表不同。
方法重写:
访问修饰符,子类的访问修饰符必须大于等于父类的访问修饰符。
方法体是没有任何要求。
其他部分必须完全一样。
方法重写:
private的方法不能被重写。
public > 默认 > private
class Animal {
public void eat(){
System.out.println("骨头");
}
public void test(){}
}
class Dog extends Animal{
public void eat(){
super.eat();
System.out.println("狗粮");
}
public void test(){ }
}
class OverrideDemo3 {
public static void main(String[] args) {
Dog d = new Dog();
d.eat();
}
}
多态:多种形态。
猫:(动物、猫科动物、猫、宠物)
狗:(动物、犬科动物、狗、宠物)
多态的前提:
1.必须有继承。
2.有方法重写。(多态的意义)
3.父类引用指向子类对象。(多态的表现)
class Animal {
public void say(){
}
public void eat(){
System.out.println("----------------------------");
}
}
class Dog extends Animal {
public void say(){
System.out.println("汪汪");
}
public void eat(){
System.out.println("啃骨头");
}
}
class DuoTaiDemo {
public static void main(String[] args) {
/*
Animal a = new Animal();
Animal a:对象的声明,对象的引用。,所以这个叫做 父类的引用。
new Animal(); //父类对象
= :指向
Dog d = new Dog();
Dog d: //子类的引用
new Dog(); //子类对象
= 指向
父类引用指向子类对象
Animal a = new Dog();
*/
Animal a = new Dog();
//a.say();
a.eat();
}
}
类型转换:
基本数据类型的转换:
自动类型转换:小范围转换为大范围。小类型转换为大类型。
int a = 10;
double d = a;
强制类型转换:
double d = 10.0;
int a = (int)d;
引用数据类型可以发生类型转换:
自动类型转换:子类会自动转换为父类。
Dog d = new Dog();
Animal a = d;
强制类型转换:逻辑上可以转换的类型转换才可以。
目标类型 变量名 = (目标类型)待转数据
Dog d1 = (Dog)a;
class Animal {
}
class Dog extends Animal {
public void kanJia(){
System.out.println("看家护院");
}
}
class Cat extends Animal {
}
class DuoTaiDemo2 {
public static void main(String[] args) {
//Animal a = new Dog();
//a.kanJia();
Dog d = new Dog();
Animal a = d;
//Dog d1 = (Dog)a;
Cat c = (Cat)a;
}
}
多态的优点”
1.提高了代码的复用性。
2.提高了代码的可维护性。
3.提高了代码的可扩展性。
//自定义一个医生类
class Doctor {
/*
//给猫看病
public void kanBing(Cat c){
c.say();
}
//给狗看病
public void kanBing(Dog c){
c.say();
}
*/
//给动物看病
public void kanBing(Animal c){
c.say();
}
}
class Animal {
public void say(){}
}
class Cat extends Animal {
public void say(){
System.out.println("喵喵");
}
}
class Dog extends Animal {
public void say(){
System.out.println("汪汪");
}
}
class Tiger extends Animal {
public void say(){
System.out.println("嗷……");
}
}
class DoctorTest {
public static void main(String[] args) {
Doctor doc = new Doctor();
//猫
//Cat c = new Cat();
//狗
//Dog c = new Dog();
/*
//Animal a = new Cat();
//Animal a = new Dog();
*/
Tiger c = new Tiger();
doc.kanBing(c);
}
}
多态里边的成员:
成员变量:不会反生覆盖。使用的时候,使用的父类的属性。
编译的时候,要看父类,父类有的我们才能用,父类没有的,我们不能使用。
运行的时候,也看父类。
成员方法:
静态成员:
class Animal {
String classify = "狗";
}
class Dog extends Animal {
String classify = "藏獒";
}
class DuoTaicybl {
public static void main(String[] args) {
//Dog d = new Dog();
//父类引用指向子类对象
Animal a = new Dog();
System.out.println(a.classify);
}
}
class Cat {
//String name = "猫";
}
class Dog extends Cat {
String name = "狗";
}
class DuoTaicybl1 {
public static void main(String[] args) {
Cat c = new Dog();
}
}
多态成员方法:
编译时:看父类,如果父类没有,我们不能使用。
运行的时候看子类。
成员方法和成员变量:
编译时(写代码的时候):
成员方法:看父类,父类有的我们才能使用,父类没有,不能使用
成员变量:看父类,父类有的我们才能使用,父类没有,不能使用
运行时:
成员变量:看父类。
成员方法:看子类。
class Animal {
public void say(){
}
}
class Dog extends Animal {
public void say(){
System.out.println("汪汪");
}
}
class DuoTaicyff {
public static void main(String[] args) {
Animal a = new Dog();
a.say();
}
}
final:最终的,不可改变的。
可以修饰;类、方法、变量。
修饰方法时:该方法不允许重写
修饰类的时候:该类不能被继承。
修饰变量时:该变量的值不允许修改。(final修饰变量时,变量有个特殊的称呼,叫做“常量”)
final修饰的成员变量,必须初始化。
class Bank{
final int a = 10;
public void balance(String s){
s = "123456";
System.out.println("给帐号"+ s +"减少1000元");
}
}
class Zi extends Bank{
public void balance(String s){
System.out.println("给帐号"+ s + "增加10W元");
}
}
class BankDemo {
public static void main(String[] args) {
Bank b = new Bank(); //new Bank();
b.balance("1");
}
}
final修饰的变量:
如果是基本数据类型的变量:不允许修改的是“值”。
如果是引用数据类型的变量:不允许修改的是“内存地址”
class Something {
public int addOne(final int x){
return 1;//++x;
}
public void addOne(final Other o) {
//o.i++;
o=new Other();
}
}
class Other {
int i;
}
class FinalTest {
public static void main(String[] args) {
}
}
总结:
继承的优点:
提高了代码的复用性和可维护性。
继承的特点:
1.只支持单继承,可以多层继承。
2.不能部分继承,继承就是全部继承,不继承就一个都不能要。
3.必须体现是is a 的关系。
继承的格式:
class 子类 extends 父类{}
子类的实例化过程:
1.先加载父类
2.加载子类
3.执行子类构造方法(在构造方法第一行,执行父类构造方法)
4.把开辟的空间的内存地址赋值给 “对象的引用”
继承中的构造方法:
super关键字:
调用父类成员。
成员变量:super.成员变量 //子类和父类的成员变量重名时,使用"super.成员变量"来访问父类的成员变量
成员方法:super.成员方法 //子类和父类有方法重写时,使用"super.成员方法"来调用父类的成员方法
构造方法:super(参数);
1.如果我们在子类构造方法中不写this、super时,系统会默认给我们添加一个super();
2.super(参数);必须放在子类构造方法中的第一行。(this和super 不能同时出现。)
方法重写:指的子父类拥有相同的方法。
1.private的方法不可以被重写。
2.构造方法不能继承,也不能重写。
3.子类的访问权限一定要大于等于父类的访问权限。
4.除了方法体和访问修饰符,其他必须保持一致。
多态:事物的多种形态。
前提:
1.必须有继承关系。
2.必须有方法重写。(多态的意义)
3.父类引用指向子类对象。(多态的表现)
多态中的成员:
编译时:都看父类,如果父类没有的,就不能使用。
运行时:除了成员方法,其他都看父类。成员方法看子类。
final关键字:
可以修饰、类、属性、方法
修饰类:则该类不能被继承。
修饰方法:则该方法不能被重写。
修饰变量:该变量不能改变。(这种不可改变的量称之为"常量")
修饰成员变量时,该变量必须初始化。
如果修饰的是基本数据类型的变量,则该变量不可改变的"值"
如果修饰的是引用数据类型的变量,则该变量不可改变的是"内存地址"