sup面向对象
例一
public class Student {
//private 本类中私有的
private String name;
private int age;
//当你定义一个类之后,这个类中,默认就存在有空参的构造方法。
//构造方法的方法名和类名相同,没有返回值,连void都没有。
//一旦,我们手动给出了,有参构造,那么默认无参构造就没有了,如果你还想借助空参构造创建对象。建议你手动把空参构造写出来。
public Student(){
System.out.println("空参的构造方法执行了");
}
public Student(String name) {
System.out.println("一个参数的构造方法执行了"+name);
}
public Student(String name,int age) {
System.out.println("两个参数的构造方法执行了"+name+"=="+age);
}
public class MyTest {
public static void main(String[] args) {
//创建一个类的对象 使用关键字new 来用构造方法来完成对类的实例化。
//构造方法的作用:就是用来对类进行实例化的。
//语法:方法名和类名相同,没有返回值。连void也没有。
//借助无参构造完成类的实例化
Student student = new Student();
//借助有参构造来完成类的实例化
Student student1 = new Student("张三");
//借助两个参数的构造方法,来完成类的实例化
Student student2 = new Student("李四", 24);
}
}
例二
public class Phone {
//权限修饰符 所代表的的范围如下 由大到小,
//public > protected>缺省的>private
//private 权限修饰符,私有的 可以修饰 成员变量,成员方法,被修饰后的成员,只能在本类中访问,外界无法直接访问。
private String name;
private String color;
private double price;
//快速生成get set 方法 按 alt+insert 弹出菜单,选getter And Setter
//通过set来赋予一个值
//setName 命名规范
public void setName(String mingzi) {
name = mingzi;
}
public void setColor(String yanse) {
color = yanse;
}
public void setPrice(double jiage) {
price=jiage;
}
//通过get给出一个值
//getName 命名规范
public String getName(){
return name;
}
public String getColor() {
return color;
}
public double getPrice() {
return price;
}
//权限修饰符 状态修饰符 返回值类型 方法名(形参列表){方法体}
//public 权限修饰符公共的,可以修饰类,成员变量。成员方法 范围最大,在任何地方都能够访问到
private void call(){
System.out.println("打电话");
}
}
public class MyTest {
public static void main(String[] args) {
Phone phone = new Phone();
//调用set方法给成员变量设置值。
phone.setName("小米");
phone.setColor("黑色");
phone.setPrice(799);
String name = phone.getName();
String color = phone.getColor();
double price = phone.getPrice();
//对于有返回值的方法,可以输出调用。
//System.out.println(phone.getName());
System.out.println(name);
System.out.println(color);
System.out.println(price);
// phone.call(); //私有方法 ,外界无法调用。
//在本类中可以创建一个方法来调用本类中的私有方法,这样在测试类中就可以通过调用新方法来使用到本类中的私有方法
}
}
例三
public class Cat {
private String name;
private int age;
//this 代表该类的一个引用,你可以理解就是该类的对象 ,哪个对象调用这个方法,方法中的this就代表那个对象。
public void setName(String name){
System.out.println("方法中this代表的那个对象:"+this);
this.name=name;
}
public void setAge(int age) {
System.out.println("方法中this代表的那个对象:" + this);
this.age= age;
}
public void show(){
System.out.println("姓名: "+this.name+" 年龄: "+this.age);
}
}
public class MyTest {
public static void main(String[] args) {
Cat cat = new Cat();
System.out.println("外键创建的:"+cat);
cat.setName("大脸猫");
cat.setAge(20);
cat.show();
//当我调用set方法时 形参的名称和成员变量的名称重名了,发现把成员变量就致盲了。
//我们想要区分出来成员变量和局部变量。我们可以使用一个关键字this来区分。
//你始终记着,方法中的this,代表那个调用者。
Cat cat2 = new Cat();
System.out.println("外键创建的222:" + cat2);
cat2.setName("大脸猫2222");
cat2.setAge(200);
cat2.show();
}
}
构造方法概述和格式
构造方法概述和作用
- 创建对象,给对象中的成员进行初始化
构造方法格式特点
- 方法名与类名相同
- 没有返回值类型,连void都没有
- 没有具体的返回值
例一
//以后,你定义一个类,私有化成员变量,提供get set 方法,提供空参构造和有参构造。
public class Teacher {
private String name;
private int age;
public Teacher(){}
public Teacher(String name,int age) {
this.name=name;
this.age=age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void sleep() {
System.out.println("睡觉");
}
}
public class MyTest {
public static void main(String[] args) {
//借助空参构造创建对象,调用set方法,来给成员变量设置值。
Teacher teacher = new Teacher();
System.out.println(teacher);
teacher.setName("王祖贤");
teacher.setAge(20);
System.out.println(teacher.getName());
System.out.println(teacher.getAge());
System.out.println("=============================");
//借助有参构造创建对象,并给对象的成员变量设置值,比较方便。
Teacher teacher1 = new Teacher("张曼玉", 20);
System.out.println(teacher1.getName());
System.out.println(teacher1.getAge());
}
}
例二
public class Dog {
private String name;
private int age;
private int sex;
//按 alt+insert 键 弹框一个框,选择对应的选项,来生成 空参 有参 构造,以及get set 方法。
//构造方法
public Dog() {
System.out.println("空参调用了");
}
public Dog(String name, int age) {
System.out.println("有参构造调了");
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
private void show(){
}
public void show2() {
show();
}
}
public class MyTest {
public static void main(String[] args) {
//借助空参构造创建对象。
Dog dog = new Dog();
dog.setName("小白");
dog.setAge(20);
System.out.println(dog.getName());
System.out.println(dog.getAge());
System.out.println("=============================");
Dog dog1=new Dog("旺财",3);
System.out.println(dog1.getName());
System.out.println(dog1.getAge());
}
}
构造方法的重载及注意事项
public class Student {
private String name;
private int age;
//当你定义一个类之后,这个类中,默认就存在有空参的构造方法。
//构造方法的方法名和类名相同,没有返回值,连void都没有。
//一旦,我们手动给出了,有参构造,那么默认无参构造就没有了,如果你还想借助空参构造创建对象。建议你手动把空参构造写出来。
//方法的重载:在同一类中、方法名相同、方法参数个数或参数类型(顺序)不同
public Student(){
System.out.println("空参的构造方法执行了");
}
public Student(String name) {
System.out.println("一个参数的构造方法执行了"+name);
}
public Student(String name,int age) {
System.out.println("两个参数的构造方法执行了"+name+"=="+age);
}
public void eat(){}
}
public class MyTest {
public static void main(String[] args) {
//创建一个类的对象 使用关键字new 来用构造方法来完成对类的实例化。
//构造方法的作用:就是用来对类进行实例化的。
//语法:方法名和类名相同,没有返回值。连void也没有。
Student student = new Student();
//借助有参构造来完成类的实例化
Student student1 = new Student("张三");
//借助两个参数的构造方法,来完成类的实例化
Student student2 = new Student("李四", 24);
}
}
注意事项
-
如果我们没有给出构造方法,系统将自动提供一个无参构造方法
-
如果我们给出了有参数构造方法,系统将不再提供默认的无参构造方法
注意:这个时候如果我们还想使用无参构造方法,就必须自己给出。建议永远自己给出无参构造方法
给成员变量赋值的两种方式
- setXxx()方法
- 构造方法
一个学生类的代码及测试
public class Student {
private String name="李四";
private int age;
//无参构造方法
public Student() {
}
//两个参数的构造方法
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public class MyTest {
public static void main(String[] args) {
Student s = new Student("王五", 25);
}
}
给成员变量赋值
- setXxx()方法
- 构造方法
输出成员变量值的方式
- 通过getXxx()分别获取然后拼接
- 通过调用show()方法搞定
一个标准手机类的代码及测试
public class Phone {
private String name;
private String color;
private double price;
//提供空参,有参构造
public Phone() {
}
public Phone(String name, String color, double price) {
this.name = name;
this.color = color;
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public void call(){
System.out.println("打电话");
}
public void sendMsg(){
System.out.println("发短信");
}
}
public class MyTest {
public static void main(String[] args) {
Phone phone = new Phone();
phone.setName("小米");
phone.setColor("白色");
phone.setPrice(200.6D);
System.out.println(phone.getPrice());
System.out.println(phone.getName());
System.out.println(phone.getColor());
System.out.println("================================");
Phone phone1=new Phone("苹果","黑色",555);
System.out.println(phone1.getName());
System.out.println(phone1.getPrice());
System.out.println(phone1.getColor());
}
}
创建一个对象的步骤
一个对象的创建过程做了哪些事情
步骤
- 加载Student.class文件进内存
- 在栈内存为s开辟空间
- 在堆内存为学生对象开辟空间
- 对学生对象的成员变量进行默认初始化
- 对学生对象的成员变量进行显示初始化
- 通过构造方法对学生对象的成员变量赋值
- 学生对象初始化完毕,把对象地址赋值给s变量
长方形案例练习
public class Rectangle {
//定义一个长方形(Rectangle)类
private double height;
private double width;
public Rectangle() {
}
public Rectangle(double height, double width) {
this.height = height;
this.width = width;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
public double getWidth() {
return width;
}
public void setWidth(double width) {
this.width = width;
}
//定义获取面积的方法
public double getArea(){
return width*height;
}
//定义获取周长的方法
public double getPerimeter(){
return (width+height)*2;
}
}
public class MyTest {
//定义一个测试类,进行测试
public static void main(String[] args) {
Rectangle rectangle = new Rectangle();
rectangle.setHeight(50D);
rectangle.setWidth(20D);
System.out.println("面积:"+rectangle.getArea());
System.out.println("周长:"+rectangle.getPerimeter());
System.out.println("================================");
Rectangle rectangle1 = new Rectangle(30,60);
System.out.println("面积:" + rectangle1.getArea());
System.out.println("周长:" + rectangle1.getPerimeter());
}
}
员工案例练习
public class employee {
//成员变量
private String name;
private int age;
private int workNum;
private double salary;
//get set方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getWorkNum() {
return workNum;
}
public void setWorkNum(int workNum) {
this.workNum = workNum;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
//无参构造
public employee(){
}
//有参构造
public employee(String name, int age, int workNum, double salary){
this.name=name;
this.age=age;
this.workNum=workNum;
this.salary=salary;
}
//成员方法
public void work(){
System.out.println("跑腿");
}
public void show(){
System.out.println("姓名" + name + ";" + "年龄" + age + ";" + "工号" + workNum + ";" + "工资" + salary);
}
}
public class MyTest {
public static void main(String[] args) {
//有参完成实例化
employee worker = new employee("鹿秀儿", 18, 0001, 9999);
System.out.println(worker.getName());
System.out.println(worker.getAge());
System.out.println(worker.getWorkNum());
System.out.println(worker.getSalary());
worker.work();
worker.show();
//无参完成实例化
employee worker2 = new employee();
worker2.setName("AA");
worker2.setAge(28);
worker2.setWorkNum(0000);
worker2.setSalary(1);
System.out.println(worker2.getName());
System.out.println(worker2.getAge());
System.out.println(worker2.getWorkNum());
System.out.println(worker2.getSalary());
worker2.work();
worker2.show();
}
}
static关键字的引入
public class employee {
public String name;
//static 静态的,可以修饰成员变量和成员方法,修饰成员变量
//此变量为一个共享变量,会被这个类的所有对象所共享
public static String country="中国";
}
public class MyTest {
//对于提供main方法作为成员入口的这个类,在这个类中,我们一般不去定义成员变量和成员方法。
//静态的变量,通过类名直接调用,不需要new对象
//多个对象可以去共享一个静态变量
public static void main(String[] args) {
employee worker1 = new employee();
worker1.name="张某";
employee worker2 = new employee();
worker2.name="李某";
System.out.println(worker1.name);
System.out.println(worker1.country);
System.out.println(worker2.name);
System.out.println(worker2.country);
}
}
static的内存图解
static关键字的特点
static关键字的特点
-
随着 类.class 的加载而加载
-
优先于对象存在
-
被类的所有对象共享
举例:同班的所有学生可以共用同一个班级编号
这个特点也在告诉我们什么时候使用静态
如果某个成员变量是被所有对象共享的,那么它就应该定义为静态的
举例:
饮水机(用静态修饰)
水杯(不能用静态修饰)
-
可以通过类名调用
其实它也可以通过对象名调用
推荐使用类名调用
静态修饰的内容一般我们称其为:与类相关的,类成员
定义静态的方法
- 在静态方法里面,不能调用非静态的方法,静态所修饰的成员,是随着类的加载而加载,是优先与对象而存在,先有的访问不到后来才有的
- 在静态方法里面,调用不到非静态的成员,只能访问静态成员
- 简单记忆,在静态方法里面,只能访问静态所修饰的成员,不能访问非静态成员
- 非静态方法,既可以访问非静态成员,也可以访问静态成员
- 静态方法中,不能存在this关键字,this本身代表的是一个该类的对象,对象是后来才有的
静态变量和成员变量的区别
-
所属不同
静态变量属于类,所以也称为类变量
成员变量属于对象,所以也称为实例变量(对象变量)
-
内存中位置不同
静态变量存储于方法区的静态区
成员变量存储于堆内存
-
内存出现时间不同
静态变量随着类的加载而加载,随着类的消失而消失
成员变量随着对象的创建而存在,随着对象的消失而消失
-
调用不同
静态变量可以通过类名调用,也可以通过对象调用,推荐使用类名调用
成员变量只能通过对象名调用
如何使用JDK提供的帮助文档
-
找到文档,打开文档
-
点击显示,找到索引,出现搜索框
-
要知道自己要找谁
-
看看这个类的结构(需不需要导包)
java.lang包下的内容不需要我们手动导入
其他包下的内容需要我们手动导入
类---------------------API文档
成员变量------------字段摘要
构造方法------------构造方法摘要
成员方法------------方法摘要
-
看这个类的说明(简单的了解一下)
-
看开始版本
-
看构造方法
-
看成员方法
看左边:是否是static的,如果是我们就不需要创建对象,直接可以使用类名调用该方法;看返回值,返回值是什么我就使用说明接收
看右边:看参数列表:参数的个数,参数的类型;要什么参数用的时候就传递什么参数
-
然后使用
学习Math类的随机数功能
打开JDK提供的帮助文档学习
-
Math类的概述
类包含用于执行基本数学运算的方法
-
Math类特点
由于Math类在java.lang包下,所以不需要导包
没有构造方法,因为它的成员全部都是静态的
-
获取随机数的方法
public static double random():返回带正号的double值,该值大于等于0.0且小于1.0。
-
获取一个1-100之间的随机数
int number = (int)(Math.random()*100)+1;
public class MyTest {
public static void main(String[] args) {
//Scanner
//Java提供的一个类,Math
//生成一个随机的小数 0--1之间的小数
for (int i = 0; i < 1000; i++) {
//上下移动代码 ctrl+shift+上下方向键
double num = Math.random();
System.out.println(num);
}
}
}
public class MyTest {
public static void main(String[] args) {
//生成随机整数 范围 1---100 之间 的整数,包含1和100
for (int i = 0; i < 1000; i++) {
int v = (int) (Math.random() * 100+1);
System.out.println(v);
}
}
}
import java.util.Scanner;
public class MyTest {
//猜数字游戏
public static void main(String[] args) {
int num = (int) (Math.random() * 100 + 1);
for (int i = 10; i > 0; i--) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个整数");
int userNum = sc.nextInt();
if(userNum>num){
System.out.println("你猜大啦");
}else if(userNum<num){
System.out.println("你猜小啦");
}else{
System.out.println("恭喜你猜对啦");
break;
}
if(i>1){
System.out.println("你还有"+(i-1)+"次机会");
}else if(i==1){
System.out.println("游戏结束");
break;
}
}
}
}
import java.util.Scanner;
public class MyTest {
//猜数字游戏升级版
public static void main(String[] args) {
int num = (int) (Math.random() * 100 + 1);
//定义四个变量来接收用户输入的值
int max;
int zhong1=0;
int zhong2=100;
int min;
for (int i = 10; i > 0; i--) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个整数");
int userNum = sc.nextInt();
if(userNum>num){
System.out.println("你猜大啦");
max=userNum;//提示下次猜测的上限
min=zhong1;//提示下次猜测的下限
System.out.println("提示:"+min+"~"+max);//输出提示
zhong2=userNum;//为猜小的情况中制造上限
}else if(userNum<num){
System.out.println("你猜小啦");
min=userNum;//提示下次猜测的下限
max=zhong2;//提示下次猜测的上限
System.out.println("提示:"+min+"~"+max);//输出提示
zhong1=userNum;//为猜大的情况中制造下限
}else{
System.out.println("恭喜你猜对啦");
break;//猜对时break结束
}
//提供游戏次数限制
if(i>1){
System.out.println("你还有"+(i-1)+"次机会");
}else if(i==1){
System.out.println("游戏结束");
break;//次数归零后break结束
}
}
}
}
代码块的概述和分类
代码块概述
- 在java中,使用{ }括起来的代码被称为代码块
代码块的分类
- 根据本其位置和声明的不同,可以区分为局部代码块,构造代码块,静态代码块,同步代码块(多线程)
常见代码块的应用
-
局部代码块
在方法中出现;限定变量生命周期,及早释放提高内存利用率
-
构造代码块
在类中方法外出现;多个构造方法中相同的代码存放到一起,每次调用构造都执行,并且在构造方法前执行
-
静态代码块
在类中方法外出现,并加上static修饰;用于给类进行初始化,在加载的时候就执行,并且只执行一次
class Student {
static {
System.out.println("Student 静态代码块"); //3
}
{
System.out.println("Student 构造代码块"); //4 6
}
public Student() {
System.out.println("Student 构造方法");//5 7
}
}
class StudentDemo {
static {
System.out.println("StudentDemo的静态代码块"); //1
}
public static void main(String[] args) {
System.out.println("我是main方法"); //2
Student s1 = new Student();
Student s2 = new Student();
}
}
继承的引入和概述
继承概述
- 多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可
- 面向对象的三大特征:封装(class),继承,多态
- Java中的继承:子类可以继承父类的成员(成员变量和成员方法。)
继承格式
- 通过extend关键字可以实现类与类的继承
- class 子类名 extends 父类名 { }
- 单独的这个类称为父类,基类或者超类;这多个类可以称为子类或者派生类
继承案例演示
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中类的继承特点
java中类的继承特点
-
java只支持单继承,不支持多继承
有些语言是支持多继承,格式:extends 类1,类2,……
-
java支持多层继承(继承体系)
public class MyTest {
public static void main(String[] args) {
//Java中继承的特点:
//1.Java中只支持单继承,一个子类只能有一个父类,但是支持多层继承。
Son son = new Son();
System.out.println(son.num);
System.out.println(son.f);
//int i=son.a;
//2.Java中子类只能继承父类非私有的成员,私有成员子类无法继承。
//3.构造方法不参与继承。
}
}
class Fu {
int num=200;
private int a=500;
}
class Father extends Fu{
int f=20000;
}
class Son extends Father{
}
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);//10
System.out.println(this.num);//100
System.out.println(super.num);//200
}
}
继承的注意事项和什么时候使用继承
继承的注意事项
- 子类只能继承父类所有非私有的成员(成员方法和成员变量)
- 子类不能继承父类的构造方法,但是可以通过super关键字去访问父类构造方法
- 不要为了部分功能而去继承
什么时候使用继承
-
继承其实体现的是一种关系:“is a”
-
采用假设法
如果有两个类A,B。只有他们符合A是B的一种,或者B是A的一种,就可以考虑使用继承
继承中成员变量的关系
-
子类中的成员变量和父类中的成员变量名称不一样
-
子类中的成员变量和父类中的成员变量名称一样
在子类中访问一个变量的查找顺序(“就近原则”)
- 在子类的方法的局部范围找,有就使用
- 在子类的成员范围找,有就使用
- 在父类的成员范围找,有就使用
- 如果还找不到,就报错
this和super的区别和应用
通过问题引出super
- 子类局部范围访问父类成员变量
this和super的区别
- this 代表的是本类对象的引用
- super 代表的是父类存储空间的标识(可以理解成父类的引用,可以操作父类的成员)
this和super的使用
-
调用成员变量
this.成员变量 调用本类的成员变量
super.成员变量 调用父类的成员变量
-
调用构造方法
this(…) 调用本类的构造方法
super(…) 调用父类的构造方法
-
调用成员方法
this.成员方法 调用本类的成员方法
super.成员方法 调用父类的成员方法
继承中构造方法的关系
子类中所有的构造方法默认都会访问父类中空参数的构造方法
为什么
-
因为子类会继承父类中的数据,可能还会使用父类的数据
-
所以,子类初始化之前,一定要先完成父类数据的初始化
-
其实:
每一个构造方法的第一句默认都是:super()
Object是超类(祖宗类),Object没有父类
继承中构造方法的注意事项
public class MyTest extends Object {
public static void main(String[] args) {
//如果是,父类没有空参构造,怎么办?
//1.你想办法,调用父类有参构造
//Zi zi = new Zi();
Zi zi1 = new Zi("aaa", 100);
}
}
//Java继承体系中的顶层父类是Object类,所有类都是直接或间接继承自他
class Fu extends Object {
int num = 100;
public Fu() {
super();
System.out.println("父类的空参构造调用了");
}
public Fu(String name) {
super();
System.out.println("父类的有参构造调用了");
}
public Fu(String name, int age) {
super();
System.out.println("父类的有参构造调用了" + name + "==" + age);
}
}
class Zi extends Fu {
public Zi() {
super("abc"); //调用父类有参构造
System.out.println("子类的空参构造调用了");
}
public Zi(String str) {
// this();和super(); 不能同时存在在构造方法里面
//
this();//调用本类空参构造
//this("abc",23); //调用本类有参参构造
System.out.println("子类的空参构造调用了");
}
public Zi(String str, int age) {
// this();和super(); 不能同时存在在构造方法里面
super(str, age);
System.out.println("子类的空参构造调用了");
}
}
父类中没有无参构造方法,子类怎么办
-
在父类中添加一个无参的构造方法
-
子类通过super去显示调用父类其他的带参的构造方法
-
子类通过this去调用本类的其他构造方法
本类其他构造也必须首先访问父类构造
-
注意事项:super(…)或者this(…)必须出现在第一条语句上
class Fu{
public int num = 10;
public Fu(){
System.out.println("fu");
}
}
class Zi extends Fu{
public int num = 20;
public Zi(){
System.out.println("zi");
}
public void show(){
int num = 30;
System.out.println(num); //30
System.out.println(this.num); //20
System.out.println(super.num); //10
}
}
class Test {
public static void main(String[] args) {
Zi z = new Zi();
z.show();
}
}
class Fu { //Fu.class
static {
System.out.println("静态代码块Fu"); //1
}
{
System.out.println("构造代码块Fu"); //3
}
public Fu() {
System.out.println("构造方法Fu"); //4
}
}
class Zi extends Fu {
static {
System.out.println("静态代码块Zi");//2
}
{
System.out.println("构造代码块Zi"); //5
}
public Zi() {
System.out.println("构造方法Zi"); //6
}
}
class Test {
public static void main(String[] args) {
//你初始化子类的时候,先要初始化父类。
Zi z = new Zi(); //请执行结果。
}
}
继承中成员方法关系
当子类的方法名和父类的方法名不一样的时候
- 子类特有的方法直接使用
当子类的方法名和父类的方法名一样的时候
-
通过子类调用方法:
先查找子类中有没有该方法,如果有就使用
在看父类中有没有该方法,有就使用
如果没有就报错
方法重写概述及其应用
什么是方法重写
- 子类中出现了和父类中一模一样的方法声明(方法名,参数列表,返回值类型),也被称为方法覆盖,方法复写
override(重写)和overload(重载)的区别
- override 子类对父类方法不满意,进行改进并覆盖父类方法
- overload 通过不同的参数区分同名方法
- overload方法可以改变返回值类型,因为它与返回值类型无关
方法重写的应用
- 当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法
- 这样既沿袭了父类的功能,又定义了子类特有的内容
方法重写的注意事项
方法重写注意事项
-
父类中私有方法不能被重写
因为父类私有方法子类根本无法继承
-
子类重写父类方法时,访问权限不能更低(public、protected、缺省的、privata)
最好就一致
-
父类静态方法,子类也必须通过静态方法进行重写
其实也算不上方法重写,但是现象确实如此
-
子类重写父类方法的时候,最好声明一模一样
final关键字概述
为什么会有final
- 由于继承中有一个方法重写的现象,而有时候我们不想让子类去重写父类的方法.这对这种情况java就给我们提供了一个关键字: final
final概述
- final关键字是最终的意思,可以修饰类、变量、成员方法
final关键字修饰类、方法以及变量的特点+修饰局部变量
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修饰引用类型,指的是,这个地址值不能再次被改变。
final Fu fu = new Fu();
System.out.println(fu);
// fu=new Fu();
// System.out.println(fu);
}
}
final class Fu{
public final void show(){
System.out.println("fu show");
}
}
完