类与对象
类的定义:
[类修饰符] class 类名[ extends 父类名] [implements 接口名列表]{
成员变量的定义;
成员方法的定义;
}
类的修饰符:
1、public:允许任何其他类访问本类3.一个源程序只能有一个public类,且源文件中有public类则,文件以public类名字命名;
2、缺省:可被当前包中的其他类访问;
3、abstract:抽象类,是所有子类的公共属性和公共方法的集合,main方法不能放在abstract定义的类中;
4、final:不能再被扩展,不能有子类;
5、extends:继承,子类继承父类;
6、implements:接口,实现接口;
成员变量
成员变量是用来描述类的数据
定义格式:[修饰符列表] 类型 变量名[=值];
成员变量修饰符:public、protected、private、static、final;//前三个不能同时存在
成员变量定义类型:八种基本数据类型、类名、接口名、数组等;
成员方法
成员方法是用来描述类的功能
定义格式:[修饰符列表] 返回值类型 方法名([参数列表]){方法体}
成员方法修饰符:public、protected、private、abstract、static、final、sychronized等//前三个不能同时存在
成员方法返回值类型:若是void,则在方法中一般没有返回值,一般用输出语句;
若不是void类型,则方法中一般用return语句,返回所定义的类型【基本数据类型、类名、接口名、数组等】
构造方法
构造方法是类中一个特殊的方法,用于在创建对象时给对象赋值,完成成员变量的初始化。可以说在创建对象时,new后面的就是构造方法。
构造方法特征:1、构造方法的方法名和类名一样;
2、构造方法没有返回值类型;
注:如果类中没有定义构造方法,那么在编译时,Java编译器会自动添加一个无参构造方法;若定义了构造方法了,则不会自动添加;且一个类可以定义多个构造方法(方法的重载)
Java对象的创建和构造方法
对象的声明:类名 对象名=new 构造方法(参数列表)
对象的使用:对象名.成员方法();
对象名.成员变量;//注意方法后面是有(),在前文中的数组的长度的length是数组的属性变量,而后面会有字符串提供了length()方法来获取字符串的长度;
包
包是Java中类的一种文件组织和管理方式,
包的作用:1、解决命名冲突问题,在同一个包中类不能重名,但不同包中可以重名;
2、通过包以及访问权限控制符可以限制不同包之间类的访问权限;
包的定义:package 包名.子包名.子包名...子包名
在windows下的访问包的命令控制符为:javac -d . 编译后包名所在的文件夹 要编译的源程序 //编译
java 全限定名//运行,全限定名即包名.类名
方法的参数传递
Java中方法的参数有四种类型,分别是值参数、引用参数、数组参数、可变参数;
1、值参数:基本数据类型,调用方法时,外部变量(实参)把值赋给形参,形参在方法体内起作用,如果方法体内修改了形参的值,方法体外的实参的值不受影响;
2、引用参数:对象类型,对象参数保存的是对象的地址,调用方法时,外部的实参把地址传递给引用类型参数,此时实参和形参是同一个对象,所以在方法体内修改了形参指向的对象的值,则实参的值也会改变;
3、数组参数:与引用参数一样存放的是地址,当方法体内修改了形参数组元素的值时,实参对应的数组元素的值也改变;
4、可变参数:在方法的参数定义时使用“...”来表示的参数,这种参数允许方法调用时传递多个实参给这个可变参数。方法的参数中只允许出现一个可变参数,若方法的参数中既有固定参数,又有可变参数,可变参数放在参数列表之后。调用方法时,可变参数既可以传递参数列表,也可以传递数组;
public class ParameterDemo {
//定义传值参数的方法,用于交换a和b的值
public void swap(int a,int b) {
int temp=a;
a=b;
b=temp;
}
//定义传引用参数的方法,用于交换a和b的值
public void swap(Date date) {
int temp=date.a;
date.a=date.b;
date.b=temp;
}
//定义数组参数的方法,用于倒序排序数组中两个元素
public void swap(int a[]) {
int temp;
for(int i=0;i<a.length/2;i++) {
temp=a[i];
a[i]=a[a.length-1-i];
a[a.length-1-i]=temp;
}
}
//定义可变参数的方法,用于把值参数调换位置,可变参数倒序排序
public void swap(int a,int b,int...x) {
int temp=a;
a=b;
b=temp;
for(int i=0;i<x.length/2;i++){
temp=x[i];
x[i]=x[x.length-i-1];
x[x.length-i-1]=temp;
}
}
//主方法,程序的入口
public static void main(String[] args) {
int m=1,n=2;
Date date=new Date(2,3);
int array1[]= {3,4},array2[]= {4,5};
ParameterDemo pd=new ParameterDemo();
pd.swap(m, n);//值参调用
System.out.println("(m,n)=("+m+","+n+")");
pd.swap(date);//引用参数,传入类参数
System.out.println("(date.a,date.b)=("+date.a+","+date.b+")");
pd.swap(array1);//数组参数调用
System.out.println("(array1[0],array1[1])=("+array1[0]+","+array1[1]+")");
pd.swap(m, n, array2);//可变参数调用传入数组
System.out.println("(m,n,array2[0],array2[1])=("+m+","+n+","+array2[0]+","+array2[1]+")");
int x=6,y=7;
pd.swap(m, n, x,y);
System.out.println("(m,n,x,y)=("+m+","+n+","+x+","+y+")");
}
}
class Date {
int a,b;
public Date(int a,int b) {
this.a=a;
this.b=b;
}
}
封装
封装是指把同一类事物的特征和行为都定义到一个类中,变成类的属性和方法。同时通过访问控制符来定义每个属性和方法的可见性。
使用private将类中的数据(成员变量)隐藏起来,控制用户对类的修改和访问数据的程度。如果需要让其他对象1使用该属性,可以定义一个public型的读取或设置该私有属性的方法。即定义一个public类型的方法getter()和setter()方法,
getter():public 返回值 getXxx(){return xxx}//getter方法用来读取这个成员变量的操作,要有返回值;
setter():public void setXxx(数据类型 参数){this.xxx=xxx}//setter方法用来对这个成员变量进行赋值,set方法中一定要有形参,形参是要赋予属性的新值;
继承
继承的概念
子类从父类中继承可以访问的数据成员和方法,方法重用的手段。父类拥有的是所有子类的共有方法和属性,但子类可以有父类中没有的方法和属性;
Java中的继承
语句:[类修饰符] class 子类名 extends 父类名{成员变量定义 成员方法定义}
//父类,人类
public class Person {
private String id,name,gender;//父类的属性变量
//父类属性变量的getter和setter方法
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
//父类的有参构造方法
public Person(String id, String name, String gender) {
this.id = id;
this.name = name;
this.gender = gender;
}
//父类的无参构造方法
public Person() {
this("", "无名", "男");//this用来调用类中的另一个构造方法
}
//父类的普通成员方法
public void eat(String food) {
System.out.println("我今天吃了"+food);
}
public void sleep(int time) {
System.out.println("我今天睡了"+time+"小时");
}
}
//子类,学生类
public class Student extends Person{
//子类自己的属性变量
private String StudentId,className;
private double score;
//子类自己属性变量的getter和setter方法
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
public String getStudentId() {
return StudentId;
}
public void setStudentId(String studentId) {
StudentId = studentId;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
//子类自己的构造方法,继承了父类的有参构造方法
public Student(String id, String name, String gender,String StudentId,String className,double score) {
super(id, name, gender);//继承父类有参构造方法
// TODO Auto-generated constructor stub
this.StudentId=StudentId;
this.className=className;
this.score=score;
}
//子类的无参构造方法
public Student() {
super();//继承父类无参构造方法
}
//子类自己的普通成员方法
public void startCourse(String courseName) {
System.out.println("今天上的课为"+courseName);//子类自己的成员方法
}
}
this与super
一个子类对象实际包含两部分,一部分是继承父类的,一部分是自己定义的,而继承父类的用super来引用,而自己定义的用this来引用。
this
this的用法:1、引用当前对象的成员变量和成员方法;
2、this来调用类中的另一个构造方法;
3、把this作为参数传递给其他方法;
public class A {
//A类中定义了add方法,能够计算两数之和
public double add(double a,double b) {
return a+b;
}
//A的abstract方法可以调用B类中的substract方法来实现两个数的差
public double substract(double x,double y) {
B b=new B(this);
//把当前对象传递给B的构造方法,这样B中的a属性就相当于是当前对象this
return b.substract(x,y);//调用b的substract方法
}
}
public class B {
A a;//a为B类中的属性,是A类型的
public B(A a) {
this.a=a;
}
//B中定义了substract方法,能够计算两个数的差
public double substract(double a,double b) {
return a-b;
}
//B中的sum方法目的是计算2个数的和,可以调用A中编好的add方法
public double sum(double x,double y) {
return a.add(x, y);
}
}
public class Main {
public static void main(String[] args) {
A a = new A();
double result = a.substract(10, 5);
System.out.println("Subtraction result: " + result);
}
}
//A中的substract方法通过创建B类的实例实现,并将自己的实例传给B的构造方法,B的substract方法内部使用B的substract方法,这种方式可以使得类B可以利用类A的实例进行进一步的操作。
super
super有两种方法:1、引用父类的成员变量或成员方法;
//方法一
public void print() {
System.out.println("Name:"+super.getName());
System.out.println("Id:"+super.getId());
System.out.println("Gender:"+super.getGender());
System.out.println("StudentId:"+this.StudentId);
System.out.println("StudentClassName:"+this.className);
System.out.println("StudentScore:"+this.score);
}//在上面代码中建立一个print()方法用于输出Student的所有属性
//方法二
public void print() {
System.out.println("name:"+this.getName());
System.out.println("Id"+this.getId());
System.out.println("gender"+this.getGender());
}//在父类中定义print()方法
public void print() {
super.print();//继承父类的print()方法
System.out.println("studentId:"+this.StudentId);
System.out.println("className:"+this.className);
System.out.println("scor:"+this.score);
}//在子类中定义print()方法
2、调用父类的构造方法;
构造方法不能被子类继承,子类只能在子类的构造方法中调用父类的构造方法,而必须调用父类的构造方法,调用语句必须写在子类构造方法的第一行;
public Student(String id, String name, String gender,String StudentId,String className,double score) {
super(id, name, gender);//继承父类有参构造方法
// TODO Auto-generated constructor stub
this.StudentId=StudentId;
this.className=className;
this.score=score;
}
综上所述,可以表示出super的三种继承写法:
1、super.父类属性变量;
2、super.父类属性方法;
3、super(父类构造方法参数列表);
//定义一个Worker的父类,有涨工资这个方法
class Worker {
private String name;
private int wage;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getWage() {
return wage;
}
public void setWage(int wage) {
this.wage = wage;
}
public Worker(String name, int wage) {
this.name = name;
this.wage = wage;
}
public void UpWage() {
this.wage=this.wage+100;
}
public void print() {
System.out.println(name+"工资为:"+wage);
}
}
//定义Manager的子类,有涨工资和涨津贴的方法
class Manager extends Worker{
private int subsidy,wage;//重新定义了一个wage变量
public int getWage() {
return wage;
}
public void setWage(int wage) {
this.wage = wage;
}
public Manager(String name, int wage,int subsidy) {
super(name, wage);//继承父类的构造方法
// TODO Auto-generated constructor stub
this.subsidy=subsidy;
}
public int getSubsidy() {
return subsidy;
}
public void setSubsidy(int subsidy) {
this.subsidy = subsidy;
}
public void UpWage() {//重写涨工资的方法,在这个方法中也有涨津贴计算
this.wage=this.wage+300;
this.subsidy=this.subsidy+200;
}
public void print() {
// super.print();
System.out.println(getName()+"wage:"+this.wage);
//这个地方输出的是涨了多少津贴,而非输出涨后的工资,因为子类重新定义了wage
System.out.println(getName()+"super wage:"+super.getWage());
System.out.println(getName()+"subsidy"+subsidy);
}
}
//主方法测试
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
Worker wr=new Worker("张三",3000);
wr.print();
Manager mr=new Manager("李四",4000,200);
mr.UpWage();
//在这个地方先调用涨工资这个方法才能涨工资,再调用print()方法后第一步才能输出所涨的工资金额
mr.print();
}
}