java入门~第九天 面向对象的继承
面向对象的封装
1.继承的引入和概述
1.继承概述:
多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这
些属性和行为,只要继承那个类即可。
2.继承格式:
通过extends关键字可以实现类与类的继承,class 子类名 extends 父类名 {} 。单独的这个类
称为父类,基类或者超类;这多个类可以称为子类或者派生类。
2.继承案例演示以及继承的好处和弊端
public class Fu {
int num=200;
public void eat(){ System.out.println("吃饭饭"); }
public void sleep(){ System.out.println("睡觉"); }
}
public class Zi extends Fu {
}
public class Mytest {
public static void main(String[] args) {
Zi zi=new Zi();
System.out.println(zi.num);
zi.sleep();
zi.eat();
}
}
Java中的继承:子类可以继承父类的成员(成员变量和成员方法),如果让类和类之间形成这
种父子继承关系,使用关键字extends。
继承的好处:a:提高了代码的复用性 b:提高了代码的维护性 c:让类与类之间产生了关
系,是多态的前提。
继承的弊端:类的耦合性增强了。
开发的原则:高内聚,低耦合。
耦合:类与类的一种依赖关系。
内聚:就是自己完成某件事情的能力。
3.Java中类的继承特点
1.Java只支持单继承,不支持多继承,一个子类只能有一个父类,但是支持多层继承。有些语
言是支持多继承,格式:extends 类1,类2,…
2.Java支持多层继承(继承体系)。
3.继承,就是把多个子类的共性部分,向上抽取到父类当中,以实现代码的复用性和维护性。
public class Mytest {
public static void main(String[] args) {
Cat cat = new Cat();
cat.age=3;
cat.name="加菲猫";
System.out.println(cat.age);
System.out.println(cat.name);
cat.eat();
cat.sleep();
cat.catcheMouse();
}
}
class Animal{
String name;
int age;
public void eat(){ System.out.println("吃饭"); }
public void sleep(){ System.out.println("睡觉"); }
}
class Cat extends Animal {
public void catcheMouse() {
System.out.println("抓老鼠");
}
}
4.继承的注意事项和什么时候使用继承
1.继承的注意事项:
a:子类只能继承父类所有非私有的成员(成员方法和成员变量)
b:子类不能继承父类的构造方法,但是可以通过super(待会儿讲)关键字去访问父类构造方法。
c:不要为了部分功能而去继承
2.什么时候使用继承:
继承其实体现的是一种关系:“is a” .
采用假设法。如果有两个类A,B。只有他们符合A是B的一种,或者B是A的一种,就可以考虑使用继承。
public class Mytest {
public static void main(String[] args) {
Zi zi=new Zi();
System.out.println(zi.num);
System.out.println(zi.x);
}
}
class Fu{
int num=30;
private int num2=56;
}
class Father extends Fu{
int x=45;
}
class Zi extends Father{
}
5.继承中成员变量的关系
1.子类中的成员变量和父类中的成员变量名称不一样。
2.子类中的成员变量和父类中的成员变量名称一样。
在子类中访问一个变量的查找顺序(“就近原则”)
a: 在子类的方法的局部范围找,有就使用
b: 在子类的成员范围找,有就使用
c: 在父类的成员范围找,有就使用
d:如果还找不到,就报错
public class Mytest {
public static void main(String[] args) {
Zi zi = new Zi();
zi.show(10);
}
}
class Fu {
int num=200;
}
class Zi extends Fu {
int num=100;
public void show(int num){
System.out.println(num);
System.out.println(this.num);
System.out.println(super.num);
}
}
6.this和super的区别和应用
1.通过问题引出super:
子类局部范围访问父类成员变量。
2.说说this和super的区别:
this 代表的是本类对象的引用
super 代表的是父类存储空间的标识(可以理解成父类的引用,可以操作父类的成员)
3.this和super的使用
a:调用成员变量
this.成员变量 调用本类的成员变量
super.成员变量 调用父类的成员变量
b:调用构造方法
this(…) 调用本类的构造方法
super(…) 调用父类的构造方法kjjhukkjc:调用成员方法
this.成员方法 调用本类的成员方法
super.成员方法 调用父类的成员方法
注意:b,c马上讲
7.继承中构造方法的关系
子类中所有的构造方法默认都会访问父类中空参数的构造方法:
因为子类会继承父类中的数据,可能还会使用父类的数据。所以,子类初始化之前,一定要先完成父类数据的初始化。
其实:
每一个构造方法的第一条语句默认都是:super()
在这里简单的提一句,Object类。否则有人就会针对父类的构造方法有疑问。Object没有父类了。
继承中构造方法的注意事项:
父类没有无参构造方法,子类怎么办?
a: 在父类中添加一个无参的构造方法
b:子类通过super去显示调用父类其他的带参的构造方法
c:子类通过this去调用本类的其他构造方法
本类其他构造也必须首先访问了父类构造
注意事项:
super(…)或者this(….)必须出现在第一条语句上。
public class Mytest extends Object{
public static void main(String[] args) {
Zi zi = new Zi("za");
System.out.println(zi.num);
}
}
class Fu extends Object{
int num=100;
public Fu() {
// super();
System.out.println("父类的空参构造调用了");
}
public Fu(String name) {
// super();
System.out.println("父类的有参构造调用了");
}
}
class Zi extends Fu {
public Zi() {
// super("abc"); //调用父类有参构造
System.out.println("子类的空参构造调用了");
}
public Zi(String str) {
// this();和super(); 不能同时存在在构造方法里面
this();//调用本类空参构造
//this("abc",23); //调用本类有参参构造
System.out.println("子类的有参构造调用了");
}
}
案例演示
看程序写结果2
class Fu {
static {
System.out.println(“静态代码块Fu”);
}
{
System.out.println("构造代码块Fu");
}
public Fu() {
System.out.println("构造方法Fu");
}
}
class Zi extends Fu {
static {
System.out.println("静态代码块Zi");
}
{
System.out.println("构造代码块Zi");
}
public Zi() {
super();
System.out.println("构造方法Zi");
}
}
class Test{
public static void main(String[] args){
Zi z = new Zi(); //请执行结果。
}
}
运行结果:静态代码块Fu
静态代码块Zi
构造代码块Fu
构造方法Fu
构造代码块Zi
构造方法Zi
8.继承中成员方法关系
1.当子类的方法名和父类的方法名不一样的时候
2.当子类的方法名和父类的方法名一样的时候
通过子类调用方法:
a: 先查找子类中有没有该方法,如果有就使用
b:在看父类中有没有该方法,有就使用
c: 如果没有就报错
public class MyTest {
public static void main(String[] args) {
Son son = new Son();
son.show();
son.test();
}
}
class Father{
int num = 20;
public void hehe(){
System.out.println("父类的方法");
}
}
class Son extends Father{
int a=2000;
int num=2;
public void show(){
System.out.println(a);
System.out.println(this.num); //2
System.out.println(super.num); //20
System.out.println(new Father().num);
}
public void test(){
//用子类对象调用的我继承的父类的方法
this.hehe();
//用的是父类空间标识,来调用的父类方法。
super.hehe();
}
}
9.方法重写概述及其应用
1.什么是方法重写
子类中出现了和父类中一模一样的方法声明(方法名,参数列表,返回值类型),也被称为方法覆盖,方法复写。
2.Override和Overload的区别?Overload能改变返回值类型吗?
方法重载:允许在一个类中定义多个同名方法,只有他们的参数列表不同(个数不同或数据类型不同);
方法重写:要有继承关系,子类出现了和父类一模一样的方法(参数个数,参数类型,返回值类型),就会发生方法覆盖的现象。
方法重载可以改变返回值类型,参数的个数,类型,都可以,只是函数名相同。
3.方法重写的应用:
当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法。这样,即沿袭了父类的功能,又定义了子类特有的内容。
public class Animal {
public void sleep(){ System.out.println("睡觉"); }
public void eat(){ System.out.println("吃饭"); }
}
public class Cat extends Animal {
@Override
public void sleep() {
System.out.println("猫趴着睡觉");
}
@Override
public void eat() { System.out.println("猫吃鱼"); }
}
public class Mytest {
public static void main(String[] args) {
Cat cat = new Cat();
cat.sleep();
cat.eat();
}
}
运行结果:猫趴着睡觉
猫吃鱼
9.方法重写的注意事项
方法重写注意事项:
a:父类中私有方法不能被重写
因为父类私有方法子类根本就无法继承
b:子类重写父类方法时,访问权限不能更低,最好就一致
c:子类重写父类方法的时候,最好声明一模一样。
d:静态方法,构造方法不参与重写
public class Phone {
public void call(){ System.out.println("打电话"); }
protected void sendMsg(){ System.out.println("打电话"); }
public static void fuShow(){
System.out.println("父类静态方法");
}
}
public class Iphone extends Phone {
@Override
public void call() {
//super沿袭父类的功能
super.call();
//扩展自己的功能
System.out.println("视频");
}
//public> protected >缺省>private 级别排名
@Override
public void sendMsg() {
System.out.println("发彩信");
}
//静态方法不参与重写
//@Override
public static void fuShow() {
System.out.println("子类静态方法");
}
}
public class Mytest {
public static void main(String[] args) {
Iphone iphone = new Iphone();
iphone.call();
Iphone.fuShow();
//静态方法可以直接用类名直接调用
iphone.fuShow();
Phone.fuShow();
}
}
10.final关键字概述
1.为什么会有final
由于继承中有一个方法重写的现象,而有时候我们不想让子类去重写父类的方法.这对这种情况java就给我们提供了一个关键字: final
2.final概述
final关键字是最终的意思,可以修饰类,变量,成员方法。
final 修饰变量,此变量为一个常量;
final 修饰方法,此方法不能被重写,只能继承;
final 修饰类,此类不能继承。
自定义常量**,常量名一般大写**
11.final关键字修饰类,方法以及变量的特点
final修饰特点:
修饰类: 被修饰类不能被继承
修饰方法: 被修饰的方法不能被重写
修饰变量: 被修饰的变量不能被重新赋值,因为这个量其实是一个常量
12.final关键字修饰局部变量
基本类型,是值不能被改变
引用类型,是地址值不能被改变
public class MyTest {
public final int A=2000;
//公共的静态常量
public static final int B = 2000;
public static void main(String[] args) {
//final 最终的,可以修饰变量,方法,类
//final 修饰变量,此变量为一个常量
//final 修饰方法,此方法不能被重写,只能继承。
//final 修饰类,此类不能继承
final int NUM=200; //自定义常量,常量名一般大写
System.out.println(MyTest.B);
//final修饰基本类型,指的是,这个值不能被再次改变。
final Fu fu = new Fu();
System.out.println(fu);
// fu=new Fu(); //final修饰引用类型,指的是,这个地址值不能再次被改变。
// System.out.println(fu);
}
}
final class Fu{
public final void show(){
System.out.println("fu show");
}
}
/*
class Zi extends Fu{ //final 修饰类,此类不能继承
}
*/
本文地址:https://blog.csdn.net/weixin_41924998/article/details/107579075