package com.fish.object; /* 在现实生活中事物与事物之间是存在关系. 球员---->球队 整体与部分关系 has a 关系 学生----->人 继承的关系 is a 关系 */ //球员类 class Player{ int num; //编码 String name; public Player(int num , String name){ this.num = num; this.name = name; } public void run(){ System.out.println(name+"开跑..."); } } //球队类 class Team{ String name; //球队的名字 Player p1; //球员1 Player p2; //球员2 Player p3; //球员3 public Team(String name,Player p1,Player p2,Player p3){ this.name = name; this.p1 = p1; this.p2 = p2; this.p3 = p3; } //开始比赛 public void startGame(){ System.out.println(name+"开赛啦!!"); } } class Demo6 { public static void main(String[] args){ Player p1 = new Player(12,"梅西"); Player p2 = new Player(7,"C罗"); Player p3 = new Player(11,"内马尔"); //球队 Team t = new Team("恒大",p1,p2,p3); t.startGame(); System.out.println("名字:"+ t.p2.name); } }
package com.fish.object; /* 目前存在的问题: 1. 无法描述清楚这两个类之间的继承关系。 2. 存在着重复代码。 面向对象的三大特征: 1. 封装 2. 继承 3. 多态. 继承:继承是通过关键字extends体现的。 继承的格式: class 类名1 extends 类名2{ } 继承要注意的事项: 1. 千万不要为了减少重复代码而去继承,只有真正存在着继承关系的时候才去继承。 2. 父类私有的成员不能被继承。 3. 父类的构造函数不能被继承。 4. 创建子类对象时默认会先调用父类无参的构造函数。 */ //人类 class Person{ String name; privateint age; public Person(String name){ this.name = name; } public Person(){ System.out.println("Person类的构造方法被调用了...."); } public void eat(){ System.out.println(name+"在吃饭..."); } } //学生类 class Student1 extends Person { // Student 就称作为Person类的子类, Person类就称作为Student的父类(超类、基类) int num; //学号 public Student1(){ System.out.println("Student类的构造方法被调用了...."); } public void study(){ System.out.println(name+"good good study , day day up"); } } class Demo7{ public static void main(String[] args){ Student1 s = new Student1(); /* s.name = "狗娃"; System.out.println("名字:"+ s.name); s.eat(); */ } }
package com.fish.object; /* 疑问: 为什么要调用父类的构造方法啊?这样子做的意义在那? 调用父类 的构造方法是可以初始化从父类继承下去的属性的。 */ class Fu1{ int x = 10; String name; public Fu1(String name){ this.name = name; System.out.println("Fu类d带参的构造方法..."); } public Fu1(){ System.out.println("Fu类无参的构造方法..."); } } class Zi1 extends Fu1{ int x = 20; public Zi1(String name){ super(name); //指定调用父类一个参数的构造函数。 } public void print(){ //子类有两份x,一个是自己的,一个是父亲的 System.out.println("子类的x= "+ this.x); System.out.println("父类的x="+super.x); } } class Demo8 { public static void main(String[] args) { Zi1 z = new Zi1("大头儿子"); System.out.println("name= "+z.name); z.print(); } }
package com.fish.object; /* super关键字: super关键字代表了父类空间的引用。 super关键字的 作用: 1. 子父类存在着同名的成员时(包括变量和方法),在子类中默认是访问子类的成员,可以通过super关键字指定访问父类的成员。 2. 创建子类对象时,默认会先调用父类无参的构造方法,可以通过super关键字指定调用父类的构造方法。通过super调用父类的构造方法时,一定要写在子类的构造方法中 super关键字调用父类构造方法要注意的事项: 1. 如果在子类的构造方法上没有指定调用父类的构造方法,那么java编译器会在子类的构造方法上面加上super()语句。 2. super关键字调用父类的构造函数时,该语句必须要是子类构造函数中的第一个语句。 3. super与this关键字不能同时出现在同一个构造函数中调用其他的构造函数。因为两个语句都需要第一个语句。 super关键字与this关键字的区别: 1. 代表的事物不一致。 1. super关键字代表的是父类空间的引用。 2. this关键字代表的是所属函数的调用者对象。 2. 使用前提不一致。 1. super关键字必须要有继承关系才能使用。 2. this关键字不需要存在继承关系也可使用。 3. 调用构造函数的区别: 1. super关键字是调用父类的构造函数。 2. this关键字是调用本类的构造函数。 */ class Fu{ int x = 10; String name; public Fu(){ System.out.println("Fu类无参的构造方法.."); } public Fu(String name){ this.name = name; System.out.println("Fu类带参的构造方法.."); } public void eat(){ System.out.println("小头爸爸吃番薯.."); } } class Zi extends Fu{ int x = 20; int num; public Zi(String name,int num){ super(name); //指定调用了父类带参的 构造方法... //this(); // 调用本类无参构造方法.. //super(); //指定调用了父类无参构造方法。。。 this.num=num; System.out.println("Zi类带参的构造方法.."); } public Zi(){ System.out.println("Zi类无参的构造方法.."); } public void print(){ System.out.println("x = " +super.x); } public void eat(){ System.out.println("大头儿子吃龙虾.."); } } class Demo9 { public static void main(String[] args) { //Zi z = new Zi("狗娃"); } }
package com.fish.object; /* 目前的问题:父类的功能无法满足子类的需求。 方法重写的前提: 必须要存在继承的关系。 方法的重写: 子父类出了同名的函数,这个我们就称作为方法的重写。 什么是时候要使用方法的重写:父类的功能无法满足子类的需求时。 方法重写要注意的事项: 1.方法重写时, 方法名与形参列表必须一致。 2.方法重写时,子类的权限修饰符必须要大于或者等于父类的权限修饰符。 3.方法重写时,子类的返回值类型必须要小于或者 等于父类的返回值类型。 4.方法重写时, 子类抛出的异常类型要小于或者等于父类抛出的异常类型。 Exception(最坏) RuntimeException(小坏) 方法的重载:在一个类中 存在两个或者两个 以上的同名函数,称作为方法重载。 方法重载的要求 1. 函数名要一致。 2. 形参列表不一致(形参的个数或形参 的类型不一致) 3. 与返回值类型无关。 */ class Animal{ //大的数据 类型 } class Fish extends Animal{ //Fish小 的数据类型。 } class Fu{ String name; public Fu(String name){ this.name = name; } public Animal eat() throws RuntimeException { System.out.println(name+"吃番薯..."); return new Animal(); } } class Zi extends Fu{ String num; public Zi(String name){ super(name);//指定调用 父类带参的构造方法 } //重写父类的eat方法 public Animal eat() throws Exception{ System.out.println("吃点开胃菜.."); System.out.println("喝点汤...."); System.out.println("吃点龙虾...."); System.out.println("吃青菜...."); System.out.println("喝两杯...."); System.out.println("吃点甜品...."); return new Animal(); } } class Demo10{ public static void main(String[] args) { Zi z = new Zi("大头儿子"); z.eat(); } }
package com.fish.object; /* 需求:使用java描述一下普通的学生、 java基础班的学生、 就业班的学生。 所有的学生都会学习。但是学习的内容不一样。 普通 的学生: 马克思列宁主义。 基础班的学生:学习的是 高等数学。 就业班学生:编程. */ //普通的学生类 class Student{ String name; //构造函数 public Student(String name){ this.name = name; } public void study(){ System.out.println(name+"学习马克思列宁主义"); } } //基础班的学生是属于学生中一种 class BaseStudent extends Student{ public BaseStudent(String name){ super(name);//指定调用父类构造函数 } //重写 public void study(){ System.out.println(name+"学习高等数学.."); } } //就业班学生 也是属于普通学生中一种 class WorkStudent extends Student{ //构造 函数 public WorkStudent(String name){ super(name); } //重写 public void study(){ System.out.println(name+"学习编程.."); } } class Demo11 { public static void main(String[] args){ //System.out.println("Hello World!"); BaseStudent s = new BaseStudent("李四"); s.study(); //创建一个就业班的学生 WorkStudent w = new WorkStudent("张三"); w.study(); } }
package com.fish.object; /* instanceof 关键字 instanceof关键字的作用:判断一个对象是否属于指定的类别。 instanceof关键字的使用前提:判断的对象与指定的类别必须要存在继承或者实现的关系。 instanceof关键字的使用格式: 对象 instanceof 类别 instanceof关键字的作用: 目前没用。在多态的场景,非常有用。 一般我们做强制类型转换之前都会使用该关键字先判断一把,然后在进行转换的。 */ class Animal{ String name; String color; public Animal(String name, String color){ this.name = name; this.color = color; } } //狗是属于动物中一种 class Dog extends Animal { public Dog(String name,String color){ super(name,color); //指定调用父类两个 参数的构造函数。 } public void bite(){ System.out.println(name+"咬人!!"); } } //老鼠 也是属于动物中一种 class Mouse extends Animal{ public Mouse(String name,String color){ super(name,color); } public void dig(){ System.out.println(name+"打洞.."); } } class Demo12{ public static void main(String[] args){ Dog d = new Dog("哈士奇","白色"); System.out.println("狗是狗类吗?"+ (d instanceof Dog)); System.out.println("狗是动物类吗?"+ (d instanceof Animal)); //System.out.println("狗是老鼠类吗?"+ (d instanceof Mouse));// false true,报错 Animal a = new Animal("狗娃","黄色"); //狗娃是人 System.out.println("动物都是狗吗?"+ (a instanceof Dog)); } }
总结:
static(静态、修饰符)
static修饰成员变量: 如果一个成员变量使用static修饰,那么该成员变量的数据就是一个共享的数据.
静态成员变量的访问方式
方式一:可以使用对象访问。
对象.属性名
方式二:可以使用类名访问。
类名.属性名
注意:
1. 非静态成员变量不能使用类名直接访问,要使用对象访问.
2. 千万不要为了访问方便而使用static修饰。一定要数据真正是需要被共享的时候才使用static修饰。
static修饰成员函数:
静态函数的访问方式
方式一:可以使用对象访问。
对象.属性名
方式二:可以使用类名访问。
类名.属性名
推荐使用类名访问静态的成员。
静态函数要注意的细节:
1. 非静态函数只能由对象调用,静态函数可以由类名或者对象进行调用。
2. 静态函数中不能直接访问非静态成员,可以直接访问静态的成员。
3. 非静态函数可以直接访问非静态成员以及可以直接访问静态的成员。
4. 静态函数中不能出现this或者super关键字。
单例设计模式:保证一个类在内存中只有一个对象。
饿汉单例设计模式:
1. 私有化构造函数。
2. 声明本类的引用类型变量并且指向本类的对象,(private static)
3. 提供一个公共静态的方法获取本类对象。
懒汉单例设计模式:
1. 私有化构造函数。
2. 声明本类的引用类型变量,但是不要创建对象。
3. 提供一个公共静态的方法获取本类对象,获取之前先判断是否已经创建了本类的对象,
如果没有创建,创建再返回。如果已经创建了,那么直接访问即可。
继承:
继承的格式:
class 类名1 extends 类名2{
}
继承要注意的事项:
1. 父类私有的成员不能被继承。
2. 父类的构造函数不能被继承。
3. 创建子类对象时,默认会先调用父类的无参构造函数,然后再调用子类 的构造函数。
super关键字:super关键字代表的是父类的引用空间。
super关键字的作用:
1. 如果子父类存在同名的成员时,在子类中默认是访问子类的成员,可以通过super关键字指定访问 父类的成员。
2. 创建子类对象时,默认会先调用父类的无参构造函数,可以通过super关键字指定调用父类的构造函数,
super关键字要注意的事项:
1. 如果在子类 的构造函数中没有指定调用具体父类构造函数,那么java编译器会在子类的构造函数上添加super()语句。
2. super关键字调用构造函数时必须出现构造函数中第一个语句。
3. this与super调用构造函数的时候不能同时出现在一个构造函数中,因为都需要是第一个语句。
方法重写:子父类存在着同名的函数。
方法重写的需求:如果父类的功能无法满足子类的需求,那么就进行重写。
方法重写的要素:
1. 函数名与形参列表必须一致。
2. 子类的权限修饰符必须大于或者等于父类 的权限 修饰符。
3. 子父类的返回值类型必须小于或者等于父类的返回值类型。
4. 子类抛出的异常类型必须要小于或者等于父类抛出的异常类型。
instanceof:判断一个对象是否属于某种类型。
instanceof关键字的使用格式:
对象 instanceof 类。
instanceof的使用前提:判断的对象与类型必须存在继承或者实现的关系。
本文出自 “小鱼的博客” 博客,谢绝转载!