类的构造
person.java
public class person {
public static void main(String[] arge){
class someone{
private String name;
private int id;
//无参构造方法,最好加上
public someone(){
}
/**
* this代表当前所在类将来所产生的对象
* 当参数和类变量重名时用this
*/
public someone(String name,int id){
this.name=name;
this.id=id;
}
public void put(){
System.out.println("name:"+name+",id:"+id);
}
}
//引用包内的类
someone aa = new someone("zhangsan",201412112);
aa.put();
}
}
person.java执行结果
访问控制
访问控制 | private成员 | 默认成员(friendly) | protected成员 | publict成员 |
---|---|---|---|---|
同一类中成员 | O | O | O | O |
同一包中其他成员 | X | O | O | O |
不同包中的子类 | X | X | O | O |
不同包中的非子类 | X | X | X | O |
- friendly不是关键字,只是一种默认修饰符的称谓。
p1:MyClass1.java
package p1;
public class MyClass1 {
public int a = 10;
private int b = 20;
protected int c = 30;
int d = 40;
public void func1() {
System.out.println("public方法 func1");
}
private void func2() {
System.out.println("private方法 func2");
System.out.println("包p1私有方法调用私有数据:"+b);
}
protected void func3() {
System.out.println("protected方法 func3");
}
void func4() {
System.out.println("friendly方法 func4");
}
}
p1:MyClass2.java
package p1;
class MyClass2 {
public void func1() {
System.out.println("public func1 of MyClass2");
}
}
p1:Test.java
package p1;
public class Test {
public void func() {
MyClass1 obj1 = new MyClass1();
//a是公共属性,任何地方都可以访问
System.out.println("公有数据:"+obj1.a);
// Error,b为私有属性,类外无法访问
//System.out.println("私有数据:"+obj1.b);
// c是受保护属性,同包的类可以访问
System.out.println("保护数据:"+obj1.c);
// d是缺省属性,同包的类可以访问
System.out.println("缺省数据:"+obj1.d);
// func1()是公共方法,任何地方都可以访问
obj1.func1();
//Error,func2()为私有方法,类外无法访问
//obj1.func2();
// func3()是受保护方法,同一包中的类可以访问,其他包中的子类也可以访问
obj1.func3();
// func4()是缺省方法,同一包中的类可以访问
obj1.func4();
// 同一包中的缺省访问控制类可以访问
MyClass2 obj2 = new MyClass2();
}
}
p2:Test.java
package p2;
import p1.MyClass1;
//Error,不能导入不同包中的缺省类
//import p1.MyClass2;
public class Test {
public void func() {
MyClass1 obj1 = new MyClass1();
// 公共属性,任何地方都可以访问
System.out.println(obj1.a);
// Error,b为私有属性,类外无法访问
//System.out.println(obj1.b);
// Error,c是受保护属性,不同包中的非子类无法访问
//System.out.println(obj1.c);
// Error,d是缺省属性,不同包中的类不能访问
//System.out.println(obj1.d);
// func1()是公共方法,任何地方都可以访问
obj1.func1();
// Error,func2()为私有方法,类外无法访问
//obj1.func2();
// Error,func3()是受保护方法,不同包中的非子类无法访问
//obj1.func3();
// Error,func4()是缺省方法,不同包中的类不能访问
//obj1.func4();
// Error,不可以访问不同包中的缺省类
//MyClass2 obj2 = new MyClass2();
}
}
p3:Test.java
package p3;
import p1.MyClass1;
//Error,不能导入不同包中的缺省类
//import p1.MyClass2;
//Test类继承了p1包中的MyClass1类
public class Test extends MyClass1 {
public void func() {
// 公共属性,任何地方都可以访问
System.out.println(a);
// Error,b为私有属性,类外无法访问
//System.out.println(b);
// c是受保护属性,子类可以访问
System.out.println(c);
// Error,d是缺省属性,不同包中的类不能访问
//System.out.println(d);
// func1()是公共方法,任何地方都可以访问
func1();
// Error,func2()为私有方法,类外无法访问
//func2();
// func3()是受保护方法,子类可以访问
func3();
// Error,func4()是缺省方法,不同包中的类不能访问
//func4();
// Error,不可以访问不同包中的缺省类
//MyClass2 obj2 = new MyClass2();
}
}
p0:main.java
package p0;
import p1.*;
public class main {
public static void main(String[] args) {
System.out.println("包p1的类调用包p1的对象");
//定义p1中的Test对象
Test p1t = new Test();
p1t.func();
System.out.println();
System.out.println("包p2的类调用包p1的对象");
//定义p2中的Test对象
p2.Test p2t = new p2.Test();
p2t.func();
System.out.println();
System.out.println("包p3的类继承包p1的类并调用p1的对象");
//定义p3中的test对象
p3.Test p3t = new p3.Test();
p3t.func();
System.out.println();
}
}
main.java
类与类之间的关系
- 1、继承与多态
- 1.1 继承
- 1.2 多态
- 1.3 super关键字
- 1.4 final关键字
- 2、其他关系
- 2.1 依赖关系
- 2.2 关联关系
- 2.3 聚合关系
- 2.4 组成关系
- 3、内部类
- 3.1 成员内部类
- 3.2 局部内部类
- 3.3 静态内部类
- 3.4 匿名内部类
1.1 继承
- java中一个类不能继承多个类
- 虽然不支持多线程,但可以用接口来妳补
- 构造方法执行的次序是:父类->子类;
语法
[访问符][修饰符] class 子类 extends 父类{
......
}
FatherClass.java
package com.demon.test5;
//父类
public class Father {
public int a;
public FatherClass() {
System.out.println("调用父类构造方法...");
a = 10;
}
}
ChildClass.java
package com.demon.test5;
//子类
public class ChildClass extends FatherClass {
int b;
public ChildClass() {
System.out.println("调用子类构造方法...");
b = 20;
}
public static void main(String[] args) {
// 实例化一个子类对象
ChildClass obj = new ChildClass();
// 输出子类中的属性值
System.out.println("a=" + obj.a + ",b=" + obj.b);
}
}
运行结果
调用父类构造方法...
调用子类构造方法...
a=10,b=20
1.2 多态
- 编译时的多态:由声明该变量所使用的类型决定。
- 运行时的多态:由实际赋给该变量的值决定。
- 一个父类具有多个子类,可以将子类的对象直接赋值给父类。
- 重写父类方法时,子类的返回值,方法名,参数,异常与父类保持一致。
- 父类中的私有方法不能被重写。
- 子类方法的可访问性必须与父类方法的可访问性一致或者更公开。
OverrideDemo.java
package com.demon.test5;
//父类
class Base {
public void print() {
System.out.println("父类");
}
}
//子类
class Son1 extends Base {
// 重写父类的print()方法
public void print() {
System.out.println("子类1");
}
}
class Son2 extends Base {
public void print() {
System.out.println("子类2");
}
}
public class OverrideDemo {
public static void main(String[] args) {
//多态
//obj指向自己
Base obj=new Base();
obj.print();
//obj指向子类Son对象
obj = new Son1();
obj.print();
//obj指向子类Son2对象
obj= new Son2();
obj.print();
}
}
运行结果
父类
子类1
子类2
1.3 super关键字
代表父类的对象
- 在子类的构造方法中调用父类的构造方法。
- 在子类的方法中访问父类的属性或者方法。
- 若子类没有明确调用父类的构造方法时,系统会自动调用父类的不带参数的构造方法,即super()方法。
mysuper.java
package com.qst.chapter05;
//父类
class Base1 {
private int a;
private int b;
public Base1(){
//系统默认调用super();时调用父类的不带参构造函数
System.out.println("父类不带参构造函数");
}
public Base1(int a,int b){
this.a=a;
this.b=b;
}
public int geta(){
return a;
}
public int getb(){
return b;
}
public void display(){
System.out.println("a="+a+",b="+b);
}
}
//子类
class Son extends Base1 {
private int c;
public Son(){
}
public Son(int a,int b,int c){
//调用父类的构造方法来初始化父类中的基础属性
super(a,b); //如果注释掉的话则调用父类不带参的构造函数
this.c=c;
}
public void display(){
// System.out.println("a="+this.geta()+",b="+this.getb()+",c="+c);
//调用父类的display()输出父类的两个属性
super.display();
System.out.println("c="+c);
}
}
public class mysuper {
public static void main(String[] args) {
//多态
//obj指向自己
Base1 obj=new Base1(1,2);
obj.display();
//obj指向子类Son对象
obj = new Son(1,2,3);
obj.display();
}
}
运行结果
a=1,b=2
a=1,b=2
c=3
注释掉39行super()的运行结果运行结果
a=1,b=2
父类不带参构造函数
a=0,b=0
c=3
1.4 final关键字
表示“不可改变、最终”的意思,用于修饰变量、方法和类。
- 修饰变量,表示常量,不能改变。
- 修饰方法,表示最终方法,不可被子类重写。
- 修饰类,表示最终类,不可悲子类继承。
2.1 依赖关系
比较常见,在一个类中操作另一个类的对象,称其依赖于第二个类。
DependentDemo.java
package com.demon.test5;
//依赖关系,Person依赖Car
class Car {
void run(String city) {
System.out.println("汽车开到" + city);
}
}
class Person {
// Car类的对象作为方法的参数
void travel(Car car) {
car.run("大连");
}
}
public class DependentDemo {
public static void main(String[] args) {
Car car=new Car();
Person p=new Person();
p.travel(car);
// new Person().travel(new Car());
}
}
运行结果
汽车开到大连
- 人出租汽车去玩,人依赖于汽车。
2.2 关联关系
一个类使用另一个类的对象作为该类的成员变量。
AssociationDemo.java
package com.demon.test5;
//关联关系,Person关联Car
class Car {
void run(String city) {
System.out.println("汽车开到" + city);
}
}
class Person {
// Car对象作为成员变量
Car car;
Person(Car car) {
this.car = car;
}
void travel() {
car.run("大连");
}
}
public class AssociationDemo {
public static void main(String[] args) {
Car car = new Car();
Person p = new Person(car);
p.travel();
// new Person(new Car()).travel();
}
}
运行结果
汽车开到大连
- 人开着自己的车去玩,人关联车。
2.3 聚合关系
关联关系的一种特例,体现整体与部分的关系。
体现在一个类由多个其他类的对象作为成员变量。
AggregationDemo.java
package com.demon.test5;
//聚合关系,Department由Employee聚合而成
class Employee {
String name;
Employee(String name) {
this.name = name;
}
}
class Department {
Employee[] emps;
Department(Employee[] emps) {
this.emps = emps;
}
void show() {
// 循环遍历
for (Employee emp : emps) {
System.out.println(emp.name);
}
}
}
public class AggregationDemo {
public static void main(String[] args) {
Employee[] emps = {
new Employee("张三"),
new Employee("李四"),
new Employee("王五")};
Department dept = new Department(emps);
dept.show();
}
}
运行结果
张三
李四
王五
2.4 组成关系
CompositionDemo.java
package com.demon.test5;
//组成关系,汽车由各设备组成
//发动机
class Engine {
}
// 底盘
class Chassis {
}
// 车身
class Bodywork {
}
// 电路设备
class Circuitry {
}
// 汽车
class Car {
Engine engine;
Chassis chassis;
Bodywork bodywork;
Circuitry circuitry;
Car(Engine engine, Chassis chassis, Bodywork bodywork, Circuitry circuitry) {
this.engine = engine;
this.chassis = chassis;
this.bodywork = bodywork;
this.circuitry = circuitry;
}
}
public class CompositionDemo {
public static void main(String[] args) {
Engine engine = new Engine();
Chassis chassis = new Chassis();
Bodywork bodywork = new Bodywork();
Circuitry circuitry = new Circuitry();
Car car = new Car(engine, chassis, bodywork, circuitry);
}
}
3. 内部类
一个类体之内在定义一个类,外面的叫外部类,里面的叫内部类。
- 能隐藏起来,不被同一包中的其他类访问。
- 能访问外部类的所有属性。
3.1 成员内部类
在外部类的内部定义一个类。
Cow.java
package com.demon.test5;
public class Cow {
private double weight;
// 外部类的两个重载的构造器
public Cow() {
}
public Cow(double weight) {
this.weight = weight;
}
// 定义一个成员内部类
private class CowLeg {
// 成员内部类的一个实例变量
private double length;
// 成员内部类的一个重载的构造方法
public CowLeg() {
}
public CowLeg(double length) {
this.length = length;
}
// 下面省略length、color的setter和getter方法
public void setLength(double length) {
this.length = length;
}
public double getLength() {
return this.length;
}
// 成员内部类的方法
public void info() {
System.out.println("高:" + length);
// 直接访问外部类的private修饰的成员变量
System.out.println("本牛腿所在奶牛重:" + weight);
}
}
public void test() {
CowLeg cl = new CowLeg(1.12);
cl.info();
}
public static void main(String[] args) {
Cow cow = new Cow(378.9);
cow.test();
}
}
运行结果
高:1.12
本牛腿所在奶牛重:378.9
- 外部类:Cow.class
- 内部类:Cow $ CowLeg.class
3.2 局部内部类
- 在方法中定义的内部类
- 不能用public和private访问修饰符进行声明。
- 作用域在方法块中
- 可以访问局部变量,但这些必须声明为final。
LocalInnerClass.java
package com.demon.test5;
public class LocalInnerClass {
public static void main(String[] args) {
// 定义局部内部类
class InnerBase {
int a;
}
// 定义局部内部类的子类
class InnerSub extends InnerBase {
int b;
}
// 创建局部内部类的对象
InnerSub is = new InnerSub();
is.a = 5;
is.b = 8;
System.out.println("InnerSub对象中:a=" + is.a + ",b=" + is.b);
}
}
运行结果
InnerSub对象中:a=5,b=8
- LocalInnerClass.class
- LocalInnerClass $ 1InnerBase.class
- LocalInnerClass $ 1InnerSub.class
- 多出来的数字一是为了区分相同名称的内部类(处于不同方法中)。
3.3 静态内部类
static修饰的内部类,将内部类变成与外部类相关
StaticInnerClassDemo.java
package com.demon.test5;
public class StaticInnerClassDemo {
private int prop1 = 5;
private static int prop2 = 9;
// private static StaticInnerClass StaticInnerClass;
static class StaticInnerClass {
// 静态内部类里可以包含静态成员
private static int age = 0;
public void accessOuterProp() {
// 下面代码出现错误:
// 静态内部类无法访问外部类的实例变量
// System.out.println(prop1);
// 下面代码正常
System.out.println(prop2);
System.out.println(age);
}
}
public static void main(String[] args){
StaticInnerClassDemo.StaticInnerClass sic = new StaticInnerClassDemo.StaticInnerClass();
sic.accessOuterProp();
}
}
运行结果
9
0
3.4 匿名内部类
AnonymousClassDemo.java
package com.demon.test5;
public class AnonymousClassDemo {
public static void main(String[] args) {
System.out.println(new Object(){
//重写toString方法
public String toString(){
return this.put();
}
public String put(){
return "这是匿名函数";
}
});
}
}
运行结果
这是匿名函数
不重写的运行结果
com.qst.chapter05.innerclass.AnonymousClassDemo$1@15db9742
网友评论