QUESTION:
1.使用debug跟踪子类对象实例化执行顺序:
package lianxi;
public class abc extends ab{
int a=0,b=0,c=0;
abc(int x)
{
super(x); a=x+7;
}
abc(int x,int y){
super(x,y);a=x+5;b=y+5;
}
abc(int x,int y,int z){
super(x,y,z);a=x+4;b=y+4;c=z+4;
}
public int add()
{
System.out.println("super:x+y+z="+super.add());
return a+b+c;
}
public static void main(String[] args) {
abc p1=new abc(2,3,5);
abc p2=new abc(10,20);
abc p3=new abc(1);
System.out.println("a+b+c="+p1.add());
System.out.println("a+b="+p2.add());
System.out.println("a="+p3.add());
}
}
package lianxi;
public class ab {
private int x=0,y=0,z=0;
ab(int x){
this.x=x;
}
ab(int x,int y){
this(x);
this.y=y;
}
ab(int x, int y,int z){
this(x,y);
this.z=z;
}
public int add() {
return x+y+z;
}
}
现在对子类进行debug测试,验证子类对象实例化执行顺序。 1.abc p1=new abc(2,3,5); 2.abc p2=new abc(10,20); 3.abc p3=new abc(1); 语句1如下所示: (1) (2) (3) (4) (5) (6) 随后进行赋值。2,3语句debug顺序与其类似。 首先进入子类的构造函数,在赋值前进入父类构造函数中,然后由于重载的原因,不断跳跃到前一个构造函数中,最后进入最终父类object中,结束后进行赋值操作。
2.如何实现两个对象之间互发消息:
可以通过对象引用的方法,创建两个类,这两个类中都包含另一个类的成员。
package lianxi;
class A{
private abc b;
public void bb(abc b){
if(b!=null){
System.out.println("ooo");
this.b=b;
}
}
public abc get(){
if(b!=null){
return b;
}
else
return null;
}
}
class abc{
private A a;
public abc(A a){
this.a=a;
a.bb(this);
}
public static void main(String[] args) {
A a=new A();
abc bb = new abc(a);
}
}
输出:
3.组合与继承的区别以及使用场景:
区别:组合现象是一个类的对象引用是另一个类的属性,对象引用可以指向其对应类的任何一个对象,但对象只能调用其规定好的方法,无法修改;继承是子类将父类的属性和方法全部继承下来,子类可以重载和覆盖父类的方法,继承具有类似一对一的属性。
宜用组合的场景:一个类的对象与另一个类的对象具有一对多关系,一个类的方法对于另一个类来说永远不用改变。
宜用继承的场景:两个类的对象具有一对一的关系,一个类需要重载或覆盖另一个类的方法;抽象类等等。
4.java运行时多态的含义与作用:
运行时多态:当同一个引用变量指向不同的子类实例,然后访问引用变量成员方法, 方法会有不同的表现。使用父类引用指向子类对象,再调用某一父类中的方法时,不同子类会表现出不同结果。 作用:运行时多态性提供了更大的灵活性,所有事情都在运行时得到解决。
package lianxi;
abstract public class Shapes {
protected int x,y,k;
protected double m;
public Shapes(int x,int y,int k,double m) {
this.x=x;
this.y=y;
this.k=k;
this.m=m;
}
abstract public double getArea();
abstract public double getPerimeter();
}
package lianxi;
import java.awt.*;
public class Rect extends Shapes{
public double getArea() {
return k*m;
}
public double getPerimeter() {
return (2*k+2*m);
}
public Rect(int x,int y,int width,int height) {
super(x,y,width,height);
}
}
package lianxi;
import java.awt.*;
public class Triangle extends Shapes{
public Triangle(int baseA,int baseB,int baseC) {
super(baseA,baseB,baseC,0);
m=(baseA+baseB+baseC)/2.0;
}
public double getArea() {
return(Math.sqrt(m*(m-k)*(m-x)*(m-y)));
}
public double getPerimeter() {
return (x+y+k);
}
}
package lianxi;
import java.awt.*;
public class Circle extends Shapes{
public Circle(int x,int y,int width) {
super(x,y,width,width/2.0);
}
public double getArea() {
return m*m*Math.PI;
}
public double getPerimeter() {
return 2*Math.PI*m;
}
}
package lianxi;
import java.awt.*;
import java.applet.*;
public class RunShape extends Applet {
Rect rect=new Rect(5,15,25,25);
Triangle tri =new Triangle(5,5,8);
Circle cir=new Circle(13,90,25);
private void drawArea(Graphics g,Shapes s,int a,int b) {
g.drawString(s.getClass().getName()+" Area"+s.getArea(),a,b);
}
private void drawPerimeter(Graphics g,Shapes s,int a,int b) {
g.drawString(s.getClass().getName()+"Perimeter"+s.getPerimeter(),a,b);
}
public void paint(Graphics g) {
g.drawRect(rect.x, rect.y, rect.k, (int)rect.m);
drawArea(g,rect,50,35);
drawPerimeter(g,rect,50,55);
drawArea(g,tri,50,75);
drawPerimeter(g,tri,50,95);
g.drawOval(cir.x-(int)cir.k/2,cir.y-(int)cir.k/2,cir.k,cir.k);
drawArea(g,cir,50,115);
drawPerimeter(g,cir,50,135);
}
}
5.使用接口改写6.8:
public interface Shapes {
public abstract double getArea();
public abstract double getPerimeter();
}
public class Rect implements Shapes{
int x,y;
double width,height;
public Rect(int x,int y,double width,double height) {
this.x=x;
this.y=y;
this.width=width;
this.height=height;
}
public double getArea() {
return width*height;
}
public double getPerimeter() {
return 2*(width+height);
}
}
public class Triangle implements Shapes {
int baseA,baseB,baseC;
double m;
public Triangle(int x,int y,int z) {
baseA=x;
baseB=y;
baseC=z;
m=(baseA+baseB+baseC)/2.0;
}
public double getArea() {
return (Math.sqrt(m*(m-baseA)*(m-baseB)*(m-baseC)));
}
public double getPerimeter() {
return (double)(baseA+baseB+baseC);
}
}
public class Circle implements Shapes{
int x,y;
double d,r;
public Circle(int x,int y,int width) {
this.x=x;
this.y=y;
r=width/2.0;
d=(double)width;
}
public double getArea() {
return (r*r*Math.PI);
}
public double getPerimeter() {
return (d*Math.PI);
}
}
import java.applet.*;
import java.awt.*;
public class RunShape extends Applet {
Rect rect=new Rect(5,15,25,25);
Triangle tri=new Triangle(5,5,8);
Circle cir=new Circle(13,90,25);
private void drawArea(Graphics g,Shapes s,int a,int b) {
g.drawString(s.getClass().getName()+"Area"+s.getArea(), a,b);
}
private void drawPerimeter(Graphics g,Shapes s,int a,int b) {
g.drawString(s.getClass().getName()+"Perimeter"+s.getPerimeter(),a,b);
}
public void paint(Graphics g) {
g.drawRect(rect.x, rect.y,(int)rect.width, (int)rect.height);
drawArea(g,rect, 50, 35);
drawPerimeter(g,rect,50,55);
drawArea(g,tri,50,75);
drawPerimeter(g,tri,50,95);
g.drawOval(cir.x-(int)cir.r,cir.y-(int)cir.r ,(int)cir.d,(int)cir.d);
drawArea(g,cir,50,115);
drawPerimeter(g,cir,50,135);
}
}
6.自定义类,覆写equals:
class Man{
private String name;
private int age;
Man(String name,int age){
this.name=name;
this.age=age;
}
public String toString(){
return this.name+"今年"+this.age+"岁";
}
public boolean equals(Object obj){
if(obj==null){
return false;
}
if(this==obj){
return true;
}
if(!(obj instanceof Man)){
return false;
}
Man per=(Man)obj;
return this.name.equals(per.name)&&this.age==per.age;
}
}
class Student{}
public class Test{
public static void main(String[] args) {
Person per1=new Man("张三",18);
Person per2=new Man("张三",18);
Person per3=new Man("lisi",19);
Person per4=null;
Student stu=new Student();
System.out.println(per1.equals(per1));
System.out.println(per1.equals(stu));
System.out.println(per1.equals(per3));
System.out.println(per1.equals(per4));
}
}
7.instanceof使用场景:
用来判断两类是否存在父类与子类的关系。 举个栗子: a为对象引用,A为类。a为A实例或A子类实例,返回true。 a为A父类实例,返回false。 a和A无关系,编译不通过。
8.抽象类与接口的异同,及使用场景:
相同点: 两者都是抽象类,都不能实例化。 interface实现类及abstract class的子类都必须要实现已经声明的抽象方法。
|