前言
上一篇文章主要介绍了有关面向对象的知识与编程,这篇短小的文章主要是针对面向对象的一个补充。
知识点:
类的主方法
主方法是类的入口点,它定义了程序从何处开始以及提供对程序流向的控制,在java中,编程都是通过主方法来执行程序。
public static main(String[] args){
//方法体
}
在主方法的定义中,我们可以看到其具有以下特征:
- 主方法是静态的,如若要直接从主方法中调用其他的方法,那么该方法也必须是静态的。
- 主方法是没有返回值的 。
- 主方法形参为数组,其中args[0]~args[n]代表着程序的第一个参数到第n个参数,可以用args.length来获取参数的个数。
类的构造函数
除了上次文章当中说到的成员方法之外,还存在一种特殊的方法,那就是构造方法,对象的创建就是通过构造方法来完成的。没当类实例一个对象时,类都会调用构造方法。
public book(){
....//构造方法体
}
构造方法的特点:
- 构造函数没有返回值。(与普通的没有返回值的方法不同。普通无返回值的方法使用public void methodEx()这种形式定义,但是构造方法并不需要使用void关键字就行修饰 )
- 构造方法的名称要与本类的名称相同。
- 构造方法中可以为成员变量赋值,当实例化一个本类对象时,相应成员变量也将被初始化。
- 类中假如没有明确定义构造方法,那么编译器会自动创建一个不带参数的默认构造方法。
继承
- 表达方式:extend 继承
- 继承:父类私有的无法继承,构造函数无法继承。
在内存空间划分父类的储存空间,再叠加子类的属性空间。 - 继承的特点:1、代码的可重用性 2、父类的属性和方法可用于子类 3、设计应用程序变得更加简单 4、子类可以拓展父类的属性和方法。
- 单继承与多继承:
某些OOP语言(例如C++)允许子类有多个父类,但在Java中这是不允许的,在Java中,一个类只能有一个父类。
所有的根类都是object。具有相同的属性,面向对象编程中,可以通过扩展一个 已有的类,并继承该类的属性和行为,来创建一个新的类, 这种方式称为继承(Inheritance)。
继承里面是类和类继承,不是对象和对象继承. - 继承:继承是通过关键字extends体现的。
继承的格式:
class 类名1 extends 类名2{
}
- 继承要注意的事项:
- 千万不要为了减少重复代码而去继承,只有真正存在着继承关系的时候才去继承。
- 父类私有的成员不能被继承。
- 父类的构造函数不能被继承。
- 创建子类对象时默认会先调用父类无参的构造函数。
- super关键字:
1.可以用在类方法和对象方法中。
2.在对象方法中可以使用super 关键字,调用当前对象从父类继承过来的对象方法。
3.在类方法中 super关键字可以调用当前类从父类继承过来的方法(类方法也能被子类继承,父类中的类方法可以使用父类名来调用,也可以使用子类名调用。再子类的类方法中,也可以用super来调用复用的类方法)
子类从父类继承:相当于模板中拥有父类莫看中的所有的成员。创建以各子类对象,仍然是根据模板来创建,子类对象中既有子类的成员,也有父类的成员
super 特指这个方法是从父类继承过来的/super是指当前类或者对象的这个方法是从父类继承过来的
工程训练(改进)
任务要求:
- 完成一个java application 应用程序,描述一个人类。要求如下:
- 要求此人类必须包含有人的姓名、性别、出生日期等基本属性(变量)。
- 要求此人类描述吃饭的方法(函数)和描述睡觉的方法(函数)。例如睡觉方法的执行体为一个 System.out.println() 函数,此函数输出一段例如“ xx(姓名)往床上躺倒,不久就睡着了……”之类的描述睡觉的文本。
- 要求此人类的构造函数要具有无参数的构造函数,以及带有姓名、性别、出生日期等参数的构造函数,并在构造函数中输出一段描述xx(姓名)出生的文本。
- 实例化出张三和李四两个人类对象(变量),并为之赋初值。
- 调用张三、李四等人类对象的各种属性(类成员变量)和方法(函数)。
- 在上述人类的基础上派生一个**
继承
自人类的新的学生类**,加入学号等学生特有的属性,加入上课、考试等方法,并实例化一个或几个学生类对象,完成这些学生类对象的各种属性和方法的调用。 - 以上定义中,各种类的属性、方法等鼓励标新立异,尽量达到可以描述真实的人类和学生等。
实现代码:
class Humanity //创建Humanity对象
{
public String name; //声明公有字段name,此时name为类的属性,下面通过公有方法进行访问
public String sex; //声明性别变量sex
public int age; //声明公共字段age
public int id; //声明人物学号变量
public String birth; //声明人物生日变量
public String getName() //返回对象的信息描述
{
return name;
}
public void setName(String name) { //设置名称
this.name = name;
}
public void eat() //定义无参数的eat方法
{
System.out.println("他是个纯南方人,特别爱吃米饭");
}
public void eat(String s) //定义带参数的eat方法,实现方法重载
{
System.out.println("他是一个地道的北方人,非常喜欢吃"+s);
}
public void sleep() { //定义无参数的sleep方法
System.out.println("张三偶尔熬夜,晚上思考能力很发达,所以睡眠时间不太好。");
}
public void sleep(String t) { //定义带参数的sleep方法,实现方法重载
System.out.println("李四有良好的休息习惯,只要往"+t+"躺倒,不久就会睡着了……");
}
public Humanity() //定义无参构造函数,注意无返回值定义,方法与类同名
{
}
public Humanity(int age,int id,String sex,String name,String birth)
{ //重写一个带参数构造函数,注意无返回值定义,方法与类同名
this.age = age; //前一个age为对象的字段,由this指定,后一个age为函数形参
this.id = id; //前一个id为对象的字段,由this指定,后一个age为函数形参
this.sex = sex; //前一个sex为对象的字段,由this指定,后一个age为函数形参
this.name = name; //前一个name为对象的属性,由this指定,因为在本类中可直接访问,后一个name为函数形参
this.birth = birth; //前一个birth为对象的字段,由this指定,后一个birth为函数形参
}
//public Humanity(int age,int id,String sex,String name) //定义无参构造函数,注意无返回值定义,方法与类同名
//{
//this.age = age; //前一个age为对象的字段,由this指定,后一个age为函数形参
//this.id = id;
//this.sex = sex;
//this.name = name;
//}
}
//创建一个Teacher子类(用extends)
class Teacher extends Humanity {
Teacher(int age,int id,String sex,String name,String birth) {
super(age, id, sex, name, birth); // 使用super()调用Humanity的构造函数
}
public void study() //定义无参数的study方法
{
System.out.println("他要求学生每天好好学习,按时上课");
}
public void study(String r) //定义带参数的study方法,实现方法重载
{
System.out.println("还建议学生在空闲时间多看"+r);
}
public void exam() //定义无参数的exam方法
{
System.out.println("无论任何考试,都要做一个诚信的人!");
}
public void exam(String q) //定义带参数的exam方法,实现方法重载
{
System.out.println("考试检测方面,不允许使用"+q+"作弊");
}
}
public class Example3
{
public static void main(String[] args) //主方法调用
{
Humanity Humanity1 = new Humanity(); //调用类的无参构造函数
Humanity1.age = 22; //给对象的公有字段直接赋值
Humanity1.id =201801234; //给对象的公有字段直接赋值
Humanity1.setName("张三"); //给对象的公有字段直接赋值
Humanity1.sex = "男" ; //给对象的公有字段直接赋值
Humanity1.birth = "1996年5月8日" ; //必须使用公共方法才能给对象的属性赋值
System.out.println("从前有个"+Humanity1.sex+"生叫"+Humanity1.getName()+",他出生于"+ Humanity1.birth+",今年"+Humanity1.age+ "岁,学号是"+Humanity1.id);
Humanity1.eat(); //调用对象的无参方法
Humanity1.sleep(); //调用对象的无参方法
System.out.println("\n"); //空行
Humanity Humanity2 = new Humanity(23,201804321,"男","李四","1995年6月9日");//调用类的有参构造函数
System.out.println("他有个"+Humanity2.sex+"同学叫" + Humanity2.getName() + ",学号为"+Humanity2.id + ",今年" + Humanity2.age+ "岁了,生日是"+Humanity2.birth);
Humanity2.eat("馒头"); //调用对象的有参方法
Humanity2.sleep("床上"); //调用对象的有参方法
System.out.println("\n"); //空行
Teacher Humanity3 = new Teacher(35,200906789,"男","杜", "1983年");
//Humanity3.age = 35; //给对象的公有字段直接赋值
//Humanity3.id =200906789; //给对象的公有字段直接赋值
//Humanity3.sex = "男" ; //给对象的公有字段直接赋值
Humanity3.setName("杜"); //给对象的公有字段直接赋值
System.out.println("他俩有一位"+Humanity3.age+"岁的"+Humanity3.sex+"导师,叫"+Humanity3.getName()+"老师,学工号:"+ Humanity3.id);
//System.out.println(Humanity3.getName());
Humanity3.study(); //调用对象的无参方法
Humanity3.study("科技类文章"); //调用对象的有参方法
Humanity3.exam("通讯设备"); //调用对象的有参方法
Humanity3.exam(); //调用对象的无参方法
//System.out.println();
}
}
效果:
多多改进,多多请教,the way!