Ⅰ 谈谈java中的继承与组合
继承和组合的概念
在新类里简单地创建原有类的对象 我们把这种方法叫作 组合 因为新类由现有类的对象合并而成 我们只是简单地重复利用代码的功能 而不是采用它的形式
第二种方法是创建一个新类 将其作为现有类的一个 类型 我们可以原样采取现有类的形式 并在其中加入新代码 同时不会对现有的类产生影响 这种魔术般的行为叫作 继承 (Inheritance) 涉及的大多数工作都是由编译器完成的 对于面向对象的程序设计 继承 是最重要的基础概念之一 对于组合和继承这两种方法 大多数语法和行为都是类似的(因为它们都要根据现有的类型生成新类型)
组合也就是一个类的对象是另外一个类的成员 一般的程序都有组合的意味 只不过是基本数据类型是成员变量 下面请看具体的例子
class Head
{
Head(){
System out println( head );
}
}
class Body
{
Body(){
System out println( body );
}
}
class Person()
{
Head h=null;
Body b=null;
Person() //人是由头和身体组成的 Head和Body的对象是Person的一部分
{
h=new Head();
b =new Body();
}
}
继承作为面向对象的三个重要特性的一个方面 在面向对象的领域有着及其重要的作用 好像没听说哪个面向对象的语言不支持继承
class Person
核扮桐{
private String name=null;
private int age= ;
public Person(String n int a)
{
name=n;
age=a;
}
int getAge()
{
return age;
}
String getName()
{
return name;
}
void getDescription()
{
System out println( name: +name+ + age: +age);
}
}
class Student extends Person
{
private String studno=null;
public Student(String n String no int a)
{
super(n a);
studno=no;
}
}
说明:Student类中有三个成员变量name age studno和一个方法getDescription();
注意:子类继承了父类的所有变量和函数 只是缺孙子类不能访问父类的private类型的变量和函数 其实privae类型的变量还是继承到子类中的
无论还是继承 都允许我们将子对象置于自己的新类中 大家或许会奇怪两者间的差异 以及到底该如何选择
如果想利用新类内部一个现有类的特性 而不想使用它的接口 通常应选择组合 也就是说 我们可嵌入一个对象 使自己能用它实现新类的特性 但新类的用户会看到我们已定义的接口 而不是来自嵌入对象的接口 考虑到这种效果 我们改坦需在新类里嵌入现有类的private对象
有些时候 我们想让类用户直接访问新类的组合 也就是说 需要将成员对象的属性变为public 成员对象会将自身隐藏起来 所以这是一种安全的做法 而且在用户知道我们准备合成一系列组件时 接口就更容易理解 car(汽车)对象便是一个很好的例子
class Engine {
public void start() {}
public void rev() {}
public void stop() {}
}
class Wheel {
public void inflate(int psi) {}
}
class Window {
public void rollup() {}
public void rolldown() {}
}
class Door {
public Window window = new Window();
public void open() {}
public void close() {}
}
public class Car {
public Engine engine = new Engine();
public Wheel[] wheel = new Wheel[ ];
public Door left = new Door()
right = new Door(); // door
Car() {
for(int i = ; i < ; i++)
wheel[i] = new Wheel();
}
public static void main(String[] args) {
Car car = new Car();
car left window rollup();
car wheel[ ] inflate( );
}
} ///:~
由于汽车的装配是故障分析时需要考虑的一项因素(并非只是基础设计简单的一部分) 所以有助于客户程序员理解如何使用类 而且类创建者的编程复杂程度也会大幅度降低
如选择继承 就需要取得一个现成的类 并制作它的一个特殊版本 通常 这意味着我们准备使用一个常规用途的类 并根据特定的需求对其进行定制 只需稍加想象 就知道自己不能用一个车辆对象来组合一辆汽车——汽车并不 包含 车辆 相反 它 属于 车辆的一种类别 属于 关系是用继承来表达的 而 包含 关系是用组合来表达的
protected
现在我们已理解了继承的概念 protected这个关键字最后终于有了意义 在理想情况下 private成员随时都是 私有 的 任何人不得访问 但在实际应用中 经常想把某些东西深深地藏起来 但同时允许访问衍生类的成员 protected关键字可帮助我们做到这一点 它的意思是 它本身是私有的 但可由从这个类继承的任何东西或者同一个包内的其他任何东西访问 也就是说 Java中的protected会成为进入 友好 状态
我们采取的最好的做法是保持成员的private状态——无论如何都应保留对基 础的实施细节进行修改的权利 在这一前提下 可通过protected方法允许类的继承者进行受到控制的访问
import java util *;
class Villain {
private int i;
protected int read() { return i; }
protected void set(int ii) { i = ii; }
public Villain(int ii) { i = ii; }
public int value(int m) { return m*i; }
}
public class Orc extends Villain {
private int j;
public Orc(int jj) { super(jj); j = jj; }
public void change(int x) { set(x); }
} ///:~
可以看到 change()拥有对set()的访问权限 因为它的属性是protected(受到保护的)
再论合成与继承
lishixin/Article/program/Java/hx/201311/26635
Ⅱ Java中,组合和继承的区别
1.组合(has-a)关系可以显式地获得被包含类(继承中称为父类)的对象,而继承(is-a)则是隐式地获得父类的对象,被包含类和父类对应,而组合外部类和子类对应。
2.组合关系在运行期决定,而继承关系在编译期就已经决定了。
3.组合是在组合类和被包含类之间的一种松耦合关系,而继承则是父类和子类之间的一种紧耦合关系。
4.当选择使用组合关系时,在组合类中包含了外部类的对象,组合类可以调用外部类必须的方法,而使用继承关系时,父类的所有方法和变量都被子类无条件继承,子类不能选择。
5.最重要的一点,使用继承关系时,可以实现类型的回溯,即用父类变量引用子类对象,这样便可以实现多态,而组合没有这个特性。
6.还有一点需要注意,如果你确定复用另外一个类的方法永远不需要改变时,应该使用组合,因为组合只是简单地复用被包含类的接口,而继承除了复用父类的接口外,它甚至还可以覆盖这些接口,修改父类接口的默认实现,这个特性是组合所不具有的。
7.从逻辑上看,组合最主要地体现的是一种整体和部分的思想,例如在电脑类是由内存类,CPU类,硬盘类等等组成的,而继承则体现的是一种可以回溯的父子关系,子类也是父类的一个对象。
8.这两者的区别主要体现在类的抽象阶段,在分析类之间的关系时就应该确定是采用组合还是采用继承。
9.引用网友的一句很经典的话应该更能让大家分清继承和组合的区别:组合可以被说成“我请了个老头在我家里干活” ,继承则是“我父亲在家里帮我干活"。
Ⅲ 关于各种排列组合java算法实现方法
一 利用二进制状态法求排列组合 此种方法比较容易懂 但是运行喊隐颂效率不高 小数据排列组合可以使用
复制代码 代码如下: import java util Arrays;//利用二进制算法进行全排列 //count : //count :
public class test { public static void main(String[] args) { long start=System currentTimeMillis(); count (); long end=System currentTimeMillis(); System out println(end start); } private static void count (){ int[] num=new int []{ }; for(int i= ;i<Math pow( );i++){ String str=Integer toString(i ); int sz=str length(); for(int j= ;j< sz;j++){ str=" "+str; } char[] temp=str toCharArray(); Arrays sort(temp); String gl=new String(temp); if(!gl equals(" ")){ continue; } String result=""; for(int m= ;m<str length();m++){ result+=num[Integer parseInt(str charAt(m)+"")]; } System out println(result); } } public static void count (){ int[] num=new int []{ }; int[] ss=new int []{ }; int[] temp=new int[ ]; while(temp[ ]< ){ temp[temp length ]++; for(int i=temp length ;i> ;i ){ if(temp[i]== ){ temp[i]= ; temp[i ]++; } } int []tt=temp clone(); Arrays sort(tt); if(!Arrays equals(tt ss)){ continue; } String result=""; for(int i= ;i<num length;i++){ result+=num[temp[i]]; } System out println(result); } } }
二 用递归的思想携慧来求排列跟组合 代码量比较大
复制代码 代码如下郑郑: package practice;import java util ArrayList; import java util List;
public class Test {
/** * @param args */ public static void main(String[] args) { // TODO Auto generated method stub Object[] tmp={ }; // ArrayList<Object[]> rs=RandomC(tmp); ArrayList<Object[]> rs=cmn(tmp ); for(int i= ;i<rs size();i++) { // System out print(i+"="); for(int j= ;j<rs get(i) length;j++) { System out print(rs get(i)[j]+" "); } System out println(); } }
// 求一个数组的任意组合 static ArrayList<Object[]> RandomC(Object[] source) { ArrayList<Object[]> result=new ArrayList<Object[]>(); if(source length== ) { result add(source); } else { Object[] psource=new Object[source length ]; for(int i= ;i<psource length;i++) { psource[i]=source[i]; } result=RandomC(psource); int len=result size();//fn组合的长度 result add((new Object[]{source[source length ]})); for(int i= ;i<len;i++) { Object[] tmp=new Object[result get(i) length+ ]; for(int j= ;j<tmp length ;j++) { tmp[j]=result get(i)[j]; } tmp[tmp length ]=source[source length ]; result add(tmp); } } return result; } static ArrayList<Object[]> cmn(Object[] source int n) { ArrayList<Object[]> result=new ArrayList<Object[]>(); if(n== ) { for(int i= ;i<source length;i++) { result add(new Object[]{source[i]}); } } else if(source length==n) { result add(source); } else { Object[] psource=new Object[source length ]; for(int i= ;i<psource length;i++) { psource[i]=source[i]; } result=cmn(psource n); ArrayList<Object[]> tmp=cmn(psource n ); for(int i= ;i<tmp size();i++) { Object[] rs=new Object[n]; for(int j= ;j<n ;j++) { rs[j]=tmp get(i)[j]; } rs[n ]=source[source length ]; result add(rs); } } return result; }
}
三 利用动态规划的思想求排列和组合
复制代码 代码如下: package Acm; //强大的求组合数 public class MainApp { public static void main(String[] args) { int[] num=new int[]{ }; String str=""; //求 个数的组合个数 // count( str num ); // 求 n个数的组合个数 count ( str num); }private static void count (int i String str int[] num) { if(i==num length){ System out println(str); return; } count (i+ str num); count (i+ str+num[i]+" " num); }
private static void count(int i String str int[] num int n) { if(n== ){ System out println(str); return; } if(i==num length){ return; } count(i+ str+num[i]+" " num n ); count(i+ str num n); } }
下面是求排列
复制代码 代码如下: lishixin/Article/program/Java/JSP/201311/20148
Ⅳ Java编程:组合,继承和代理的区别
组合的话,是在类中new一个对象,然后就只能调用这个对象的方法了,是死的
而你用代理的话,代理不仅要new那个对象,还要把你想调用这个对象的方法也写出来,方法实现是通过这个new的对象来实现的,当然你也可以在方法中添加你自己想实现的功能,这样做又有了继承中重写的感觉,所以说代理是继承和组合的中庸之道,lz可以看看thinking in java7.3章 7.4章 还有网页链接这篇博客,写的很详细
Ⅳ java中什么叫组合
组合就是 A类的对象是B类的成员变量。相当于 A类是B类对象的一个属性!
组合和继承都很常见的!